我们如何使用 --patch-module 从 OpenJDK 11 覆盖 java.base/java.lang.Integer?
How can we overwrite java.base/java.lang.Integer from OpenJDK 11 using --patch-module?
在 JDK-8 中,我们可以编译更改后的 java.lang classes 并重建 rt.jar
。然后我们可以通过使用 -Xbootclasspath:<yourpathto>/rt.jar
增加引导 class 路径来覆盖 java.lang class 文件。这样做,例如,我们可以使 java.lang.Integer 成为非最终的以用于测试目的。
在JDK-11中,这是不同的。修补是通过 --patch-modules
完成的,但我无法让它工作。我做了以下事情:
- 删除 final 修饰符并从 openjdk-11 源代码重新编译 java.base 模块
- 添加了
--patch-module java.base=<path-to-my-compiled-java.base-directory>
- 它在
error: cannot inherit from final Integer
上仍然失败。可能我们不能再覆盖 JDK 源文件的 class 声明?那就奇怪了。
- 我还尝试将这些 class 文件添加到 jar 中,并尝试将所有可能的根目录传递给
--patch-module
参数
- 我尝试从编译的
java.base
目录中删除模块 package-info.class
并尝试显式添加 java.base.java.lang.Integer
和 --add-opens
docs 对这个特定用法不是很清楚。
来自 maven 的整个 javac 命令(我已经尝试了 javac 和 maven-compiler-plugin):
javac -d ./target/classes -classpath <classpathfiles> -sourcepath <sourcefiles> -s ./target/generated-sources/annotations -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
?
Project Jigsaw 中的示例为您的 use-case 建模。注意对 javac 和 java.
使用 --patch-module
--patch-module
Developers that checkout java.util.concurrent classes from Doug Lea's CVS will be used to compiling the source files and
deploying those classes with -Xbootclasspath/p.
-Xbootclasspath/p has been removed, its module replacement is the option --patch-module to override classes in a module. It can also be
used to augment the contents of module. The --patch-module option is
also supported by javac to compile code "as if" part of the module.
Here's an example that compiles a new version of
java.util.concurrent.ConcurrentHashMap and uses it at run-time:
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 ...
检查您的源路径是否与您的 --patch-module 目录一致,即是否有文件 src/java.base/java/lang/Integar.java 并且它在您的源路径中?
更新
这是一个演示如何隐藏 java.lang.Integer 的示例项目:https://dl.dropbox.com/s/6swet2k89vukxbm/patch.zip
编译:
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 --patch-module java.base=mypatches/java.base -classpath target com.example.RunMe
在 JDK-8 中,我们可以编译更改后的 java.lang classes 并重建 rt.jar
。然后我们可以通过使用 -Xbootclasspath:<yourpathto>/rt.jar
增加引导 class 路径来覆盖 java.lang class 文件。这样做,例如,我们可以使 java.lang.Integer 成为非最终的以用于测试目的。
在JDK-11中,这是不同的。修补是通过 --patch-modules
完成的,但我无法让它工作。我做了以下事情:
- 删除 final 修饰符并从 openjdk-11 源代码重新编译 java.base 模块
- 添加了
--patch-module java.base=<path-to-my-compiled-java.base-directory>
- 它在
error: cannot inherit from final Integer
上仍然失败。可能我们不能再覆盖 JDK 源文件的 class 声明?那就奇怪了。 - 我还尝试将这些 class 文件添加到 jar 中,并尝试将所有可能的根目录传递给
--patch-module
参数 - 我尝试从编译的
java.base
目录中删除模块package-info.class
并尝试显式添加java.base.java.lang.Integer
和--add-opens
docs 对这个特定用法不是很清楚。
来自 maven 的整个 javac 命令(我已经尝试了 javac 和 maven-compiler-plugin):
javac -d ./target/classes -classpath <classpathfiles> -sourcepath <sourcefiles> -s ./target/generated-sources/annotations -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
?
Project Jigsaw 中的示例为您的 use-case 建模。注意对 javac 和 java.
使用 --patch-module
--patch-module
Developers that checkout java.util.concurrent classes from Doug Lea's CVS will be used to compiling the source files and deploying those classes with -Xbootclasspath/p.
-Xbootclasspath/p has been removed, its module replacement is the option --patch-module to override classes in a module. It can also be used to augment the contents of module. The --patch-module option is also supported by javac to compile code "as if" part of the module.
Here's an example that compiles a new version of java.util.concurrent.ConcurrentHashMap and uses it at run-time:
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 ...
检查您的源路径是否与您的 --patch-module 目录一致,即是否有文件 src/java.base/java/lang/Integar.java 并且它在您的源路径中?
更新
这是一个演示如何隐藏 java.lang.Integer 的示例项目:https://dl.dropbox.com/s/6swet2k89vukxbm/patch.zip
编译:
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 --patch-module java.base=mypatches/java.base -classpath target com.example.RunMe