为什么 Java 11 运行时会忽略我包含 sun.misc 类 的 jar?
Why is the Java 11 runtime ignoring my jar containing sun.misc classes?
我正在尝试将我的代码库升级到 Java11。不幸的是,我的代码依赖于内部使用 sun.misc.BASE64Encoder
和 Decoder
的第三方库。由于 sun.misc
包已从 Java 11 JRE 中删除,因此它失败了。该库的所有者尚未替换该依赖项,所以我坚持了一段时间。
如果我能控制代码,我会使用 java.util.BASE64 类,但正如我所说,这些是作为来自另一个库的传递依赖项出现的,我无法更改它。
我以为我会很聪明,只用那些 类 创建一个新的 jar,但由于某种原因,那个 jar 被忽略了。
<dependency>
<groupId>sun.misc</groupId>
<artifactId>BASE64</artifactId>
<version>1.8</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/sun.jar</systemPath>
</dependency>
我也试过将它明确地添加到类路径中,但仍然没有成功
这是 JRE 阻止您使用的软件包之一,还是我遗漏了某些模块规范,或者这是一个表演障碍?
这是输出
java.lang.NoClassDefFoundError: sun/misc/BASE64Encoder
at com.propsco.util.support.PropsLoader.save(PropsLoader.java:478) ~[props-client-2.2.1.jar:na]
在过去的版本中,Sun 竭尽全力确保没有办法像您现在尝试的那样篡改运行时(如果像这样简单,每个人都可以创建自己的私有变体运行时 - 你肯定会明白这不是一件好事)。我不知道细节,但它们可能归结为 "if package name is this or that or such or so, then loading will only happen from rt.jar" - 硬编码在类加载器的东西中。这些执法措施(或类似措施)似乎很可能仍然有效。
舍弃了我的其余回答,因为我认为您非常了解您的选择是什么,而这不是问题所在。
这个答案是用
写的
> java --version
openjdk 11.0.3 2019-04-16
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.3+7)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.3+7, mixed mode)
首先,您创建将具有覆盖 BASE64Encoder
的项目。我们称它为 sun-misc-override
。在 src\main\java
下使用 BASE64Encoder
class 创建 sun.misc
包。
package sun.misc;
public class BASE64Encoder {
public String encode(byte[] aBuffer) {
return "Fake it until you make it!";
}
}
如果你尝试编译它,你会得到一个 sun\misc\BASE64Encoder.java:1: error: package exists in another module: jdk.unsupported
错误。
这给了我们一个提示,我们需要 patch module jdk.unsupported
. This is because classes from the original sun.misc
package have been moved to the jdk.unsupported
module when the module system was rolled out in Java 9 and then over time removed (see JEP-260)。
使用 Maven,您可以像这样配置您的编译器插件:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>11</release>
<compilerArgs>
<arg>--patch-module</arg>
<arg>jdk.unsupported=${project.basedir}/src/main/java</arg>
</compilerArgs>
</configuration>
</plugin>
构建 com.example:sun-misc-override:1.0.0-SNAPSHOT
后,将生成的 JAR 放入您的 "main" 项目中 - 就像您所做的那样。在 lib
目录中。我还没有找到使它与常规 Maven 依赖项一起工作的方法。
现在,在您的 "main" 项目中配置编译器插件:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>11</release>
<compilerArgs>
<arg>--patch-module=jdk.unsupported=${project.basedir}/lib/sun-misc-override-1.0.0-SNAPSHOT.jar</arg>
</compilerArgs>
</configuration>
</plugin>
(可能是由于 MCOMPILER-311 我在尝试使用
时遇到了 NPE
<compilerArgs>
<arg>--patch-module</arg>
<arg>jdk.unsupported=${project.basedir}/lib/sun-misc-override-1.0.0-SNAPSHOT.jar</arg>
</compilerArgs>
尽管该错误本应由 maven-compiler-plugin 3.8.0 修复,并且它在 sun-misc-override
的 POM 中运行良好。)
现在我的 "main" 项目叫做 j11
并且有一个 class:
package com.example;
import sun.misc.BASE64Encoder;
public class BASE64EncoderTest {
public static void main(String[] args) {
System.out.println("Testing - " + new BASE64Encoder().encode(new byte[0]));
}
}
要运行需要再次指定--patch-module
:
> java --patch-module=jdk.unsupported=lib\sun-misc-override-1.0.0-SNAPSHOT.jar -cp target\j11-1.0.0-SNAPSHOT.jar com.example.BASE64EncoderTest
Testing - Fake it until you make it!
我正在尝试将我的代码库升级到 Java11。不幸的是,我的代码依赖于内部使用 sun.misc.BASE64Encoder
和 Decoder
的第三方库。由于 sun.misc
包已从 Java 11 JRE 中删除,因此它失败了。该库的所有者尚未替换该依赖项,所以我坚持了一段时间。
如果我能控制代码,我会使用 java.util.BASE64 类,但正如我所说,这些是作为来自另一个库的传递依赖项出现的,我无法更改它。
我以为我会很聪明,只用那些 类 创建一个新的 jar,但由于某种原因,那个 jar 被忽略了。
<dependency>
<groupId>sun.misc</groupId>
<artifactId>BASE64</artifactId>
<version>1.8</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/sun.jar</systemPath>
</dependency>
我也试过将它明确地添加到类路径中,但仍然没有成功
这是 JRE 阻止您使用的软件包之一,还是我遗漏了某些模块规范,或者这是一个表演障碍?
这是输出
java.lang.NoClassDefFoundError: sun/misc/BASE64Encoder
at com.propsco.util.support.PropsLoader.save(PropsLoader.java:478) ~[props-client-2.2.1.jar:na]
在过去的版本中,Sun 竭尽全力确保没有办法像您现在尝试的那样篡改运行时(如果像这样简单,每个人都可以创建自己的私有变体运行时 - 你肯定会明白这不是一件好事)。我不知道细节,但它们可能归结为 "if package name is this or that or such or so, then loading will only happen from rt.jar" - 硬编码在类加载器的东西中。这些执法措施(或类似措施)似乎很可能仍然有效。
舍弃了我的其余回答,因为我认为您非常了解您的选择是什么,而这不是问题所在。
这个答案是用
写的> java --version
openjdk 11.0.3 2019-04-16
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.3+7)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.3+7, mixed mode)
首先,您创建将具有覆盖 BASE64Encoder
的项目。我们称它为 sun-misc-override
。在 src\main\java
下使用 BASE64Encoder
class 创建 sun.misc
包。
package sun.misc;
public class BASE64Encoder {
public String encode(byte[] aBuffer) {
return "Fake it until you make it!";
}
}
如果你尝试编译它,你会得到一个 sun\misc\BASE64Encoder.java:1: error: package exists in another module: jdk.unsupported
错误。
这给了我们一个提示,我们需要 patch module jdk.unsupported
. This is because classes from the original sun.misc
package have been moved to the jdk.unsupported
module when the module system was rolled out in Java 9 and then over time removed (see JEP-260)。
使用 Maven,您可以像这样配置您的编译器插件:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>11</release>
<compilerArgs>
<arg>--patch-module</arg>
<arg>jdk.unsupported=${project.basedir}/src/main/java</arg>
</compilerArgs>
</configuration>
</plugin>
构建 com.example:sun-misc-override:1.0.0-SNAPSHOT
后,将生成的 JAR 放入您的 "main" 项目中 - 就像您所做的那样。在 lib
目录中。我还没有找到使它与常规 Maven 依赖项一起工作的方法。
现在,在您的 "main" 项目中配置编译器插件:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>11</release>
<compilerArgs>
<arg>--patch-module=jdk.unsupported=${project.basedir}/lib/sun-misc-override-1.0.0-SNAPSHOT.jar</arg>
</compilerArgs>
</configuration>
</plugin>
(可能是由于 MCOMPILER-311 我在尝试使用
时遇到了 NPE<compilerArgs>
<arg>--patch-module</arg>
<arg>jdk.unsupported=${project.basedir}/lib/sun-misc-override-1.0.0-SNAPSHOT.jar</arg>
</compilerArgs>
尽管该错误本应由 maven-compiler-plugin 3.8.0 修复,并且它在 sun-misc-override
的 POM 中运行良好。)
现在我的 "main" 项目叫做 j11
并且有一个 class:
package com.example;
import sun.misc.BASE64Encoder;
public class BASE64EncoderTest {
public static void main(String[] args) {
System.out.println("Testing - " + new BASE64Encoder().encode(new byte[0]));
}
}
要运行需要再次指定--patch-module
:
> java --patch-module=jdk.unsupported=lib\sun-misc-override-1.0.0-SNAPSHOT.jar -cp target\j11-1.0.0-SNAPSHOT.jar com.example.BASE64EncoderTest
Testing - Fake it until you make it!