为什么Java 11运行时会忽略包含sun.misc类的jar?

为什么Java 11运行时会忽略包含sun.misc类的jar?,java,java-11,Java,Java 11,我正在尝试将我的代码库升级到Java11。不幸的是,我的代码依赖于内部使用sun.misc.BASE64Encoder和解码器的第三方库。由于sun.misc包已从Java11JRE中删除,因此失败。该库的所有者还没有替换该依赖项,因此我会坚持使用它一段时间 如果我能控制代码,我会使用java.util.BASE64类,但正如我所说的,这些类是作为另一个库的可传递依赖项引入的,我无法改变这一点 我认为我会很聪明,用这些类创建一个新的jar,但是由于某种原因,这个jar被忽略了 在过去的版本中,

我正在尝试将我的代码库升级到Java11。不幸的是,我的代码依赖于内部使用
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!