12

Before Jigsaw it was quite easy to replace one or several classes in OpenJDK (to perform some test or make a contribution). I could copy an original file from OpenJDK source, for example, java/util/ArrayList.java into src/java/util/, add any changes I want, then compile it normally (outputting to mypatch directory):

$ javac.exe src\java\util\ArrayList.java -d mypatch

After that I could launch JVM with -Xbootclasspath/p to replace original ArrayList with the patched one:

$ java -Xbootclasspath/p:mypatch MyTestClass

However this does not work anymore since Jigsaw integration in Java 9-ea+111. The compilation command reports tons of errors starting like this:

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
                   ^

And even if I compile with older JDK, then JVM cannot start:

-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.

How to make patches for JDK with Jigsaw?

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334

2 Answers2

12

From the javac error message you can know that the class you're compiling belongs to the java.base module. Now to compile the JDK class you have to specify the module it belongs with --patch-module argument:

$ javac --patch-module java.base=src -d mypatch \
      src/java.base/java/util/ArrayList.java

Now to replace existing classes with the new ones use --patch-module <module-name> JVM argument:

$ java --patch-module java.base=mypatch MyTestClass

Here we should specify the directory which contains subdirectories named like the corresponding modules. Now everything works as before. You may specify this several times if you patched several modules:

$ java --patch-module java.base=mypatch --patch-module java.xml=myxmlpatch MyTestClass
Mirza
  • 53
  • 7
Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
  • 1
    Note that the `-Xpatch` syntax you are using is an old form, that will disappear soon - see [the mailing list](http://mail.openjdk.java.net/pipermail/jigsaw-dev/2016-March/007079.html). – Nicolai Parlog Mar 29 '16 at 08:45
  • Thanks, I will update the answer once it will change. Seems that currently new form doesn't work for JDK packages. – Tagir Valeev Mar 29 '16 at 08:54
  • @TagirValeev I am getting this error `javac: invalid flag: -Xmodule:jdk.jshell` I ran the command with, `javac -Xmodule:jdk.jshell -d bin/ --source-path src/ src/jdk/jshell/execution/JDIInitiator.java` Did I miss something? – JackDaniels Oct 09 '17 at 08:33
  • I have found and posted the answer to this question. Thanks – JackDaniels Oct 10 '17 at 04:51
  • The `-Xmodule` option was removed - [Jack's answer](https://stackoverflow.com/a/46658807/2525313) shows how to do it without it. – Nicolai Parlog Oct 10 '17 at 07:14
  • @JackDaniels thanks for the hint. I edited my answer in order not to confuse people and made it a community wiki answer. – Tagir Valeev Oct 10 '17 at 12:04
3

Here is the new solution that works with the released version of jdk 9.

javac --patch-module java.base=src -d mypatches/java.base \
    src/java.base/java/util/ArrayList.java

java --patch-module java.base=mypatches/java.base ...

Source: Project Jigsaw: Module System Quick-Start Guide

Prags
  • 2,457
  • 2
  • 21
  • 38
JackDaniels
  • 985
  • 9
  • 26