为什么Java 11运行时会忽略包含sun.misc类的jar?
我正在尝试将我的代码库升级到Java11。不幸的是,我的代码依赖于内部使用为什么Java 11运行时会忽略包含sun.misc类的jar?,java,java-11,Java,Java 11,我正在尝试将我的代码库升级到Java11。不幸的是,我的代码依赖于内部使用sun.misc.BASE64Encoder和解码器的第三方库。由于sun.misc包已从Java11JRE中删除,因此失败。该库的所有者还没有替换该依赖项,因此我会坚持使用它一段时间 如果我能控制代码,我会使用java.util.BASE64类,但正如我所说的,这些类是作为另一个库的可传递依赖项引入的,我无法改变这一点 我认为我会很聪明,用这些类创建一个新的jar,但是由于某种原因,这个jar被忽略了 在过去的版本中,
sun.misc.BASE64Encoder
和解码器的第三方库。由于sun.misc
包已从Java11JRE中删除,因此失败。该库的所有者还没有替换该依赖项,因此我会坚持使用它一段时间
如果我能控制代码,我会使用java.util.BASE64类,但正如我所说的,这些类是作为另一个库的可传递依赖项引入的,我无法改变这一点
我认为我会很聪明,用这些类创建一个新的jar,但是由于某种原因,这个jar被忽略了
在过去的版本中,Sun竭尽全力确保没有办法像您现在尝试的那样篡改运行时(如果像这样简单,每个人都可以创建自己的运行时私有变体——当然您会明白这不是一件好事)。我不知道细节,但它们可能归结为“如果包名是this或that或诸如此类,那么只从rt.jar加载”——在classloaders中硬编码。这些执法措施(或类似措施)很可能仍然有效
取消了我其余的答案,因为我认为你非常了解你的选择,而这不是问题所在。这个答案是用
> 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
类创建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存在于另一个模块中:jdk.unsupported
error
这提示我们需要jdk.unsupported
。这是因为当模块系统在Java 9中推出时,原始的sun.misc
包中的类已被移动到jdk.unsupported
模块中,然后随着时间的推移被删除(请参阅)
使用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>
(可能是因为我尝试使用时得到了NPE
<compilerArgs>
<arg>--patch-module</arg>
<arg>jdk.unsupported=${project.basedir}/lib/sun-misc-override-1.0.0-SNAPSHOT.jar</arg>
</compilerArgs>
要运行它,您需要再次指定--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!
请解释“但是出于某种原因,这个罐子被忽略了。”你的应用程序是一个模块化应用程序吗?你在base64编码器/解码器方面面临什么错误?你能说得更具体一点吗?你在日志中看到NoClassDefFoundError吗?你能把堆栈跟踪附加到这个问题上吗?是的@ZhekaKozlov,我添加了输出权限,你曾试图将其添加到“JAVA_HOME/jmods”中的系统库中现在。好的,它可能与noew选项--patch module
有关。请参阅sun/misc位于jdk.unsupported.jmod模块中。cli上的参数可能类似于--patch modulename=yourmodule.jmod
在旧的Java版本中,如果更改引导类路径,您可以替换rt.jar
(我认为标志是-XX:bootclasspath
?)。但我不知道这与Java 9+中的新模块系统如何交互。@Erwin Smout我怀疑这就是问题所在。
<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>
<compilerArgs>
<arg>--patch-module</arg>
<arg>jdk.unsupported=${project.basedir}/lib/sun-misc-override-1.0.0-SNAPSHOT.jar</arg>
</compilerArgs>
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]));
}
}
> 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!