【发布时间】:2019-07-05 05:58:30
【问题描述】:
我正在尝试在 Java 11 中做同样的事情,这可以在 pre java 9 中使用 -Xbootclasspath/p:path 完成。
作为一个简单的例子,我修改了java.lang.Integer 的valueOf 方法之一并编译了项目:
javac --module-source-path=src/java.base --patch-module java.base=src/java.base -d mods $(find src -name '*.java')
然后我运行了一个简单的示例:
java --patch-module java.base=<pathToMyModifiedJavaBaseClasses> -p lib -m my.moduleA/my.moduleA.Main
这很有效,我看到显示的修改(我从valueOf 做的一个简单打印输出)。
但是,当我尝试对 java.lang.ClassLoader 执行相同操作时,在执行程序时出现以下错误(编译有效):
Error occurred during initialization of boot layer
java.lang.LinkageError: loader 'bootstrap' attempted duplicate class definition for java.lang.invoke.SimpleMethodHandle.
我什至不需要对java.lang.ClassLoader 进行更改。我的补丁文件夹中该类的绝对存在似乎引发了这个错误。 (我只想在类的底部添加一个字段)
注意:我只是认为当ClassLoader 类使用 Eclipse 编译时它可以工作。我知道的少数区别之一是 Eclipse 编译器似乎还没有遵循JEP 280。但是javac 产生的字节码中也有invokedynamic 指令,所以我怀疑这是问题所在。
【问题讨论】:
-
Dp 分享你对
ClassLoader所做的更改,你试图用它来修补现有模块。 -
@nullpointer 我尝试了各种更改,最初我想简单地添加一个字段并更改 loadClass 中的某些内容。但我只是认为只有文件夹中的类就足以出现此错误,无需更改。
-
@ZhekaKozlov 感谢您的评论,但我相信您在功能上谈论的是前者
java.endorsed.dirs,不是吗?我没有在任何地方读到不允许修补 java.base。事实上,它甚至取决于所使用的编译器,正如您从上面的描述中看到的那样。因此,如果您能分享一些技术细节或链接到确认“您不应该......”的规范,我将不胜感激。 -
对不起,忘了我说的话。
java.base确实不是可升级的模块,但这与补丁无关。我混淆了这两个不相关的事情。如果需要,您可以修补java.base。
标签: java classpath java-11 java-module java-platform-module-system