Friday, October 5, 2018

Understanding ordering with JavaScript async methods

So I challenged someone in a code review to prove that there code that made use of async functions wouldn't be susceptible to a race condition. To that end I came up with a very trivial code example to demonstrate the issue, worth trying to write down the output and line orderings before you read on.

let list;

async function clearList () {
    list = []; // A
}

async function processList (processList) {
   await clearList(); // B
   list = list.concat(processList); // C
}

processList([1,2,3]); // D
processList([4,5,6]) // E
   .then(() => {
      console.dir(list); // F
   }) 

So the two questions here are what is the output of this code and what order do the lines of code get executed in. Now the point of the code was that it would show that the output is [1,2,3,4,5,6] because of the race condition; but the actual ordering of the execution of the lines of code I had wrong.

My assumption was that you would not enter the async method directly and instead be queued to be performed on a later clock tick. This gave me an execution flow of D,E,B,B,A,A,C,C,F which I was happy with until my coworker Millan Kuchtiak pointed out I was entirely incorrectly.

It turns out that at least in Chrome and Safari that code doesn't get transferred queue until you reach the first await call. So actually when you run the code through with a debugger the flow is D,B,A,E,B,A,C,C,F. This make sense from a performance point of view, some async methods might never need the change of context, so just in time async.

To summarise an async method is synchronous up until the first await

Wednesday, August 8, 2018

Trusting a self signed certificate in Oracle Visual Builder Cloud

When you are setting up a development environment you sometimes need to use self signed certificates or a separate developer CA, in order to use this in VBCS you will need to make sure that these certificates are trusted by the kss://system/trust store and have the latest 18.3.3 patches.

To do this you need to head to /em aka "Fusion Middleware Control" for your instance and navigate to the keystore page for the domain.



You then need to navigate to the system/trust keystore and select manage:



The simply import your certificate, it need to be in .pem format so you might need to do some conversion depending on what you have lying about (Note if you dragged and dropped the certificate from Chrome you can just convert using openssl x509 -inform der -in certificate.cer -out certificate.pem):


This should now be trusted, you may have to restart the Breeze war in order to see the changes take effect.

Wednesday, January 31, 2018

Quick Debugger Tip, where was that class loaded from.

Often when it is Friday afternoon and you want to go home early you come across an intractable class loading issue. You might grep your application server home, examine all the domains you can find. (I was looking at weblogic) And still you cannot find out where the class is coming from.

Now you can use the debugger in your IDE of choice to get hold of the class loader; but in this case the parent class loader had upwards of 300 jar files in it so this was going to be a pain to be sure. So it occurred there was a quicker way, just use the standard method getResource to ask the class loader which jar the file was coming from:


Turned out someone has installed SOA on this particular weblogic install, and all the relevant files were in a different directory root: this is why my original grep didn't find the jar files.

Thursday, June 15, 2017

Interpreting wpad.dat using jrunscript from JDK 8 to work out the right proxy.

In many environments you find that the correct proxy can only be fetched by parsing http://wpad/wpad.dat, which is a pain because it is actually a JavaScript file. Working out the right proxy to call for say a unix environment is a bit of a fiddle particularly if you company is huge and requires different proxies for different countries. JDK 8 to the rescue, as you can run a simple script in the Nashorn environment to get the suggested proxy for one host and use that for everything:

jrunscript -e "`curl -o - -s http://wpad/wpad.dat` function isPlainHostName(hostname) { return hostname.indexOf('.')==-1;}; var proxyList = FindProxyForURL('http://github.com','github.com'); var firstProxy = proxyList.split(';')[0].trim(); print('DIRECT'.equals(firstProxy) ?  '' : 'http://' + firstProxy.split(' ')[1]);"

Depending on your local environment you might have to implement one or more functions from the list that your wpad.dat expects, in our case I needed to implement isPlainHost.

The last part of the script just picks the first proxy name, as the function returns a list of PROXY is suggested order. The raw output looks like this:

PROXY london.example.com:80; PROXY sf.example.com:80; DIRECT;

So we just pick the first one with http as the prefix, as some tools such as docker are fussy about this, or returns an empty string if DIRECT is recommended.

http://london.example.com:80

Tuesday, March 14, 2017

The "debugger" reserved word in JavaScript

This is a handy little tip for cases where you just can't get your debugger to start in the right context or the framework you are using doesn't give you a clear path to know when you file might be loaded. (For example ABCS, or Application Builder Cloud Service, that I am currently working on has this problem)

In this case just add the debugger statement in your javascript and voila when run in a browser the debugger is popped up.

   someCode().then(value => {
       debugger;
   });


Always pays to read the reserved word list when learning a new language, you never know what you might find.

Monday, August 15, 2016

What is bound to generic types for method references in java 8, types and exceptions

So most of the time you are probably aware of method references that either reference instance of static methods directly, and they are useful but not necessarily that interesting.

Integer example = 1;

// We can bind the instance variables, in this case just the return type is bound but there couple be method parameters also
Supplier<String> s = example::toString;

// We can bind to static method, here the generic parameter are the method parameter and return type
Supplier<Long> f = System::currentTimeMillis;
Function<Integer,Integer> f = example::compareTo;


A less common formulation is to pass in instance methods and find the first generic parameter of of the function to be the type, this allows you to easily pass in a range of actions to operate on a common type:

Function<Integer,String> f = Integer::toString

For example you can create an equals method that works on a subset of properties using functions mapped to instance methods as in the above example:

public static <T> boolean equals(T one, T two, Function<? super T, ?>... accessors) {

    if (one == two) {
        return true;
    } else  if (one==null || two==null) {
        return false;
    }

    return Stream.of(accessors).allMatch(accessor ->
        Objects.equals(accessor.apply(one),accessor.apply(two)));
}

if (equals(one, two, Thing::getName, Thing:getOtherProperty)) ...;



Finally you can also bind the exception thrown from the method to one of the generic parameters. (Here I am using ThrowingException and ThrowingSupplier my home brew interfaces that are like there namesakes but have a generic parameter E for the exception thrown) This allows you to make you "closure" transparent to exceptions. This is more useful in a lot of cases when compared to the Stream throw nothing and "throws Exception" extremes.

ThrowingException<String,Integer,NumberFormatException> te = Integer::parseInt;


You can write funky closure methods that will throw different exceptions based on the passed in method reference does, no more catch (Exception).

public static <T, E extends Exception> T withCC(Class<?> contextClass, 
   ThrowingSupplier<T,E> action) throws E {

    Thread t = Thread.current();
    ClassLoader cl = t.getContextClassLoader();
    try {
        t.setContextClassLoader(contextClass.getClassLoader());
        return action.get();
    } finally {
        s.setContextClassLoader(cl);
    }
}
       

// Throws IOException, complier knows that this method call throws IOException

String value = withCC(Example.class, () -> {
    ...
    ... new FileOutpuStream(file); ...
    ...
});

// Throws another exception, complier knows that this method call throws RMIExeption

String value = withCC(Example.class, () -> {
        ...
        throw new RMIException();
    });


Once you understand the last two, method reference start to become far more interesting.

Thursday, June 2, 2016

Getting a name for someone to connect back to your server.

When doing test automation it is often the case you need to know the name of the current machine in order to prompt another machine to connect to it, particularly if you are running your tests in parallel. This week I was trying to get the server under test to connect back to a WireMock server running on the slave test machine.

The standard response on stack overflow is to use the following pattern to get a network address. In my version here if we can't resolve the name then we are assuming we are running on a developers laptop on VPN so all the tests are run on the same machine. (Hence localhost)

String hostName = "localhost";
try {
    InetAddress addr = InetAddress.getLocalHost();
    String suggestedName = addr.getCanonicalHostName();
    // Rough test for IP address, if IP address assume a local lookup
    // on VPN
    if (!suggestedName.matches("(\\d{1,3}\\.?){4}") && !suggestedName.contains(":")) {
        hostName = suggestedName;
    }
} catch (UnknownHostException ex) {
}

System.out.println(hostName);

The problem comes is that we have to trust the local machine settings, for example /etc/hostname, which can result in a network name that is not accessible from another machine. To counter this I wrote the following code to work over the available network interfaces to find a remotely addressable network address name that can be used to talk back to this machine. (I could use an IP address but they are harder to remember, particularly as we are moving towards IPv6)

String hostName = stream(wrap(NetworkInterface::getNetworkInterfaces).get())
        // Only alllow interfaces that are functioning
        .filter(wrap(NetworkInterface::isUp))
        // Flat map to any bound addresses
        .flatMap(n -> stream(n.getInetAddresses()))
        // Fiter out any local addresses
        .filter(ia -> !ia.isAnyLocalAddress() && !ia.isLinkLocalAddress() && !ia.isLoopbackAddress())
        // Map to a name
        .map(InetAddress::getCanonicalHostName)
        // Ignore if we just got an IP back
        .filter(suggestedName -> !suggestedName.matches("(\\d{1,3}\\.?){4}")
                                 && !suggestedName.contains(":"))
        .findFirst()
        // In my case default to localhost
        .orElse("localhost");

System.out.println(hostName);

You might notice there a are a few support methods being used in there to tidy up the code, here are the required support methods if you are interested.

@FunctionalInterface
public interface ThrowingPredicate<T, E extends Exception>{

    boolean test(T t) throws E;
}

@FunctionalInterface
public interface ThrowingSupplier<T, E extends Exception>{

    T get() throws E;
}

public static <T, E extends Exception> Predicate<T> wrap(ThrowingPredicate<T, E> th) {
    return t -> {
        try {
            return th.test(t);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    };
}

public static <T, E extends Exception> Supplier<T> wrap(ThrowingSupplier<T, E> th) {
    return () -> {
        try {
            return th.get();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    };
}

// http://stackoverflow.com/a/23276455
public static <T> Stream<T> stream(Enumeration<T> e) {
    return StreamSupport.stream(
            Spliterators.spliteratorUnknownSize(
                    new Iterator<T>() {
                public T next() {
                    return e.nextElement();
                }

                public boolean hasNext() {
                    return e.hasMoreElements();
                }
            },
                    Spliterator.ORDERED), false);
}