如何使用 Vert.x JavaScript 动态加载 JAR 文件?

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

使用Vert.x JavaScript (3.8.4),我想在运行时动态加载一个JAR文件。这是必要的,因为当我的 Vert.x 应用程序启动时该文件可能不存在。理想情况下,我希望能够使用这样的代码:

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

我怎样才能做到这一点?

您可能会发现此答案有帮助:

How to access external JAR files from JavaScript using Rhino and Eclipse?

另一种有效的方法是为 jar 提供其他方式,即不通过 javascript 实现,然后检查它是否可用,如果不可用则处理.

    java.lang.Class.forName( 'com.mydynamicpackage.MyCustomClass' )

如果 MyCustomClass 不存在,这将引发错误。

如果您无法确定它们是从不可信的来源加载的,那么在运行时加载 jar 可能不是一个好主意。至少 java 世界是这样。

基于 this 答案,我创建了以下 JavaScript 函数用于从 JAR 文件动态加载 class:

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);
    }
})();

相当于我在问题中发布的片段是:

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

到目前为止,我只在 JRE8 中用 Vert.x 3.8.5 运行 测试过这个,也就是说,我不能说这是否也适用于旧的 Vert.x 版本或 JRE9+。