【发布时间】:2018-10-22 10:26:29
【问题描述】:
我一直在使用来自https://apimeister.com/2015/06/27/add-jar-to-the-classpath-at-runtime-in-jjs.html 的反射技术在运行时在 java 的 nashorn jjs 中加载类。
它在 java 8 中有效,但在 java 9 中却不行。我知道https://stackoverflow.com/a/41265267/5891192 中提到的推荐的命令行解决方法
根据https://stackoverflow.com/a/45970885/5891192,这种使用= 而不是标志和它的参数之间的空格的替代语法似乎也应该是有效的(因为通过-J--... 将jvm args 传递给jjs 的nashorn 方法是需要的)
有什么提示吗?
这行得通...(java 8)...
$ wget -q http://central.maven.org/maven2/org/apache/poi/poi/4.0.0/poi-4.0.0.jar
$ /usr/lib/jvm/java-1.8.0/bin/jjs -scripting loadit.js -- poi-4.0.0.jar
DONE
这不是... (java 9) ...
$ wget -q http://central.maven.org/maven2/org/apache/poi/poi/4.0.0/poi-4.0.0.jar
$ /usr/lib/jvm/java-9/bin/jjs -J--add-opens=java.base/java.net=ALL-UNNAMED -scripting loadit.js -- poi-4.0.0.jar
Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make protected void java.net.URLClassLoader.addURL(java.net.URL) accessible: module java.base does not "opens java.net" to module jdk.scripting.nashorn.scripts
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337)...
这里是 loadit.js ...
// loadit.js
function addUrlToClasspath(pth) {
var s = java.lang.ClassLoader.getSystemClassLoader();
var C = Java.type("java.lang.Class[]");
var p = new C(1); p[0] = java.net.URL.class;
var m = java.net.URLClassLoader.class.getDeclaredMethod("addURL", p);
var O = Java.type("java.lang.Object[]"); var a = new O(1); var f = new java.io.File(pth); m.setAccessible(true);
var u = f.toURL(); a[0] = u; m.invoke(s, a);
}
addUrlToClasspath($ARG[0]);
print("DONE")
编辑:2018 年 10 月 23 日:更正了“这不是 (java 9)”示例命令行
【问题讨论】:
-
系统类加载器不是 URLClassLoader,所以这个 hack 是行不通的。您是否考虑过创建自己的 URLClassLoader?
-
这是涵盖此内容的 JDK 9 发行说明:oracle.com/technetwork/java/javase/…。没有支持在运行时扩展类路径的方法(只有工具代理可以这样做)。所以我认为你需要远离你正在做的事情,可能创建你自己的 URLClassLoader 实例并调用它来加载你正在寻找的类。
-
哦,怀疑...
System.out.println(ClassLoader.getSystemClassLoader() instanceof URLClassLoader);怎么样? -
从 JDK 11 开始,您不需要为此使用 JavaScript,因为现在,
java本身可以启动简单的 Java 源代码文件。例如,请参阅dzone.com/articles/…。在这些“脚本”中,可以使用整个 Java API,包括类加载器。
标签: java reflection java-9 jjs