如何使用Jigsaw集成修补OpenJDK 9?

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)