Tag*_*eev 11 java jvm javac java-platform-module-system java-9
在Jigsaw之前,很容易在OpenJDK中替换一个或多个类(执行一些测试或做出贡献).我可以复制从OpenJDK的来源的原文件,例如,java/util/ArrayList.java进入src/java/util/,加上我想任何更改,然后编译正常(输出到mypatch目录):
$ javac.exe src\java\util\ArrayList.java -d mypatch
Run Code Online (Sandbox Code Playgroud)
之后,我可以启动JVM -Xbootclasspath/p来替换原来ArrayList的补丁:
$ java -Xbootclasspath/p:mypatch MyTestClass
Run Code Online (Sandbox Code Playgroud)
但是,自从Java 9-ea + 111中的Jigsaw集成以来,这不再起作用了.编译命令报告大量错误,如下所示:
src\java\util\ArrayList.java:26: error: package exists in another module: java.base
package java.util;
^
src\java\util\ArrayList.java:108: error: cannot find symbol
public class ArrayList<E> extends AbstractList<E>
^
symbol: class AbstractList
src\java\util\ArrayList.java:109: error: cannot find symbol
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
^
Run Code Online (Sandbox Code Playgroud)
即使我使用较旧的JDK编译,然后JVM也无法启动:
-Xbootclasspath/p is no longer a supported option.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
Run Code Online (Sandbox Code Playgroud)
如何使用Jigsaw为JDK制作补丁?
Tag*_*eev 11
从javac错误消息中,您可以知道您正在编译的类属于该java.base模块.现在要编译JDK类,您必须使用--patch-module参数指定它所属的模块:
$ javac --patch-module java.base=src -d mypatch \
src/java.base/java/util/ArrayList.java
Run Code Online (Sandbox Code Playgroud)
现在用新的类替换现有的类使用--patch-module <module-name>JVM参数:
$ java --patch-module java.base=mypatch MyTestClass
Run Code Online (Sandbox Code Playgroud)
在这里,我们应该指定包含名为相应模块的子目录的目录.现在一切都和以前一样.如果修补了几个模块,可以多次指定:
$ java --patch-module java.base=mypatch --patch-module java.xml=myxmlpatch MyTestClass
Run Code Online (Sandbox Code Playgroud)