vert.xnashorndynamic-class-loaders

How to dynamically load a JAR file with Vert.x JavaScript?


Using Vert.x JavaScript (3.8.4), I want to dynamically load a JAR file at runtime. This is necessary because that file might not exist when my Vert.x application gets started. Ideally, I would like to be able to use code like this:

// load custom JAR file
requireJar("path/to/dynamic.jar");
// use class from dynamically loaded package
var instance = new com.mydynamicpackage.MyCustomClass();

How can I achieve this?


Solution

  • Based on this answer, I have created the following JavaScript function for dynamically loading a class from a JAR file:

    var requireJavaClass=(function(){
        var method=java.net.URLClassLoader.class.getDeclaredMethod("addURL",java.net.URL.class);
        method.setAccessible(true);
        var cache={};
        var ClassLoader=java.lang.ClassLoader;
        var File=java.io.File;
        return function(classname,jarpath){
            var c=cache[classname];
            if (c) return c;
            if (jarpath) {
                var cl=ClassLoader.getSystemClassLoader();
                method.invoke(cl,new File(jarpath).toURI().toURL());
                cl.loadClass(classname);
            }
            return cache[classname]=Java.type(classname);
        }
    })();
    

    The equivalent to the snippet I posted in the my question would be:

    var MyCustomClass=requireJavaClass("com.mydynamicpackage.MyCustomClass","path/to/dynamic.jar");
    var instance = new MyCustomClass();
    

    So far, I have only tested this with Vert.x 3.8.5 running in JRE8, i.e. I can't say if this also works in older Vert.x versions or with JRE9+.