如何使用--patch模块覆盖OpenJDK 11中的java.base/java.lang.Integer?
在JDK-8中,我们可以编译更改后的java.lang类并重构如何使用--patch模块覆盖OpenJDK 11中的java.base/java.lang.Integer?,java,java-11,java-module,openjdk-11,bootclasspath,Java,Java 11,Java Module,Openjdk 11,Bootclasspath,在JDK-8中,我们可以编译更改后的java.lang类并重构rt.jar。然后我们可以通过使用-Xbootclasspath:/rt.jar扩展bootclasspath来覆盖java.lang类文件。这样做,我们可以使java.lang.Integer成为非最终的,用于测试目的 在JDK-11中,这是不同的。补丁是通过--补丁模块完成的,我无法让它工作。我已经做了以下工作: 从openjdk-11源代码中删除最后一个修饰符并重新编译java.base模块 添加了--补丁模块java.base
rt.jar
。然后我们可以通过使用-Xbootclasspath:/rt.jar
扩展bootclasspath来覆盖java.lang类文件。这样做,我们可以使java.lang.Integer成为非最终的,用于测试目的
在JDK-11中,这是不同的。补丁是通过--补丁模块完成的,我无法让它工作。我已经做了以下工作:
从openjdk-11源代码中删除最后一个修饰符并重新编译java.base模块
添加了--补丁模块java.base=
它仍然失败于错误:无法从最终整数继承。也许我们不能再覆盖JDK源文件的类声明了?那会很奇怪
我还尝试将这些类文件添加到jar中,并尝试将所有可能的根目录传递给--patch module
参数
我已尝试从编译的java.base
目录中删除模块package info.class
,并尝试使用--add opens
显式添加java.base.java.lang.Integer
关于这个特殊用法,我们还不太清楚
来自maven的整个javac命令(我已经尝试了javac和maven编译器插件):
javac-d./target/classes-classpath-sourcepath-s./target/generated sources/annotation-g-nowarn-target 11-source 11-encoding UTF-8-patch module=java.base=../runtimejar/mods/src/java.base-Xplugin:Manifold
(为了便于阅读,缩短了路径名等)
我错过了什么?为什么我不能像这样修改java.base/java.lang.Integer
?来自用例模型的示例。请注意,javac和java都使用了--patch模块
--补丁模块
从Doug Lea的CVS签出java.util.concurrent类的开发人员将用于编译源文件和
使用-Xbootclasspath/p部署这些类
-Xbootclasspath/p已被删除,其模块替换为选项--patch module以覆盖模块中的类。也可以是
用于扩充模块的内容。--patch模块选项是
javac还支持编译模块中“好像”部分的代码
下面是一个编译新版本的
java.util.concurrent.ConcurrentHashMap并在运行时使用它:
javac --patch-module java.base=src -d mypatches/java.base \
src/java.base/java/util/concurrent/ConcurrentHashMap.java
java --patch-module java.base=mypatches/java.base ...
检查sourcepath是否与--patch module目录对齐,即是否有文件src/java.base/java/lang/Integar.java,是否在sourcepath中
更新
下面是一个示例项目,演示如何对java.lang.Integer进行阴影处理:
汇编:
javac --patch-module java.base=src -d mypatches/java.base src/java.base/java/lang/Integer.java
javac --patch-module java.base=mypatches/java.base -d target src/main/java/com/example/MyInteger.java src/main/java/com/example/RunMe.java
运行:
您是否尝试过使用--补丁模块java.base=../runtimejar/mods/src\../runtimejar/mods/src/java.base/java/lang/Integer.java
?@Naman,我刚刚尝试过,仍然得到相同的错误:无法从最终整数继承。我们不应该用编译的.class文件来修补模块吗?如果你真的想更改JDK类,你最好使用JDK的源代码,修改它并构建你自己的JDK。你还应该考虑到有更好的、更干净的方法来实现你想要的,而不是修改<代码>整数< /代码>。删除<代码> -目标< /代码>命令行参数。我已经看到了来自拼图的例子,我有点迷失在如何正确地将它翻译成我的用例。我想用补丁的java.base.java.lang.Integer
编译我的项目。来自Jigsaw的示例似乎只编译了ConcurrentHashMap
?我还需要用补丁的java.base
编译javac
。我还需要在编译时使用新的补丁java.lang.Integer
。为了清楚起见,您没有在包java.base.java.lang中创建Integer类,对吧?@MGG正如您所知,将其称为java.base.java.lang.Integer
会让人困惑。这意味着包名是java.base.java.lang
。最好只说“来自java.base
模块的java.lang.Integer
类”,或者像堆栈跟踪那样使用java.base/java.lang.Integer
。您甚至不必提及该模块,因为模块系统禁止拆分包(而java.base
模块中的类,尤其是java.lang
包中的类,众所周知),因此只能有一个java.lang.Integer
。@MGG没问题。感谢您在Manifold上发布这个问题,我已经记录了这个问题,将在本周晚些时候发布的下一个版本中修复。@MGG A“java.lang.Integer
这不是最终版本”听起来您计划给自己带来大麻烦…
java --patch-module java.base=mypatches/java.base -classpath target com.example.RunMe