修补jdk.Java 17中不支持的模块



由于各种原因,我需要继续使用Java 17中的一些sun.misc类,特别是BASE64Decoder类。(该类使用的算法具有其他base 64解码器无法复制的一些特定行为。)我计划使用OpenJDK 8中提供的rt.jar文件作为这些类的源文件,并且我正在修补jdk.unsupported模块。

使用下面的示例类,我可以使用javac --patch-module=jdk.unsupported=/path/to/rt.jar TestDecoder.java 编译它
import sun.misc.BASE64Encoder;
public class TestDecoder {
public static void main(String[] args) {
System.out.println(new BASE64Encoder().encode(new byte[0]));
}
}

似乎在Java 17之前的Java版本中,可以使用patch-module来运行它:

java --patch-module=jdk.unsupported=/path/to/rt.jar  
-cp /path/to/rt.jar 
TestDecoder.class

然而,在Java 17中,这在java.lang.module.ResolutionException: Module jdk.unsupported contains package java.time.zone, module java.base exports package java.time.zone to jdk.unsupported中失败了。好像是从java开始的。基本导出到jdk。不支持,不可能修补jdk。不支持的模块。有什么办法可以解决这个问题吗?

版本:

$ java --version
openjdk 17.0.2 2022-01-18
OpenJDK Runtime Environment (build 17.0.2+8-86)
OpenJDK 64-Bit Server VM (build 17.0.2+8-86, mixed mode, sharing)
$ javac --version
javac 17.0.2

(这个问题的Java 11版本是:为什么Java 11运行时忽略了包含sun的jar。misc课吗?,这是而不是那个问题的重复。)

正如在注释中提到的,问题是拆分包。也就是说,你不能有两个模块定义同一个包(java.time. net)。

如果您想走--patch-module路由,则不能使用整个rt.jar。您必须创建一个jar文件,其中只包含sun.misc中需要的类。

对于base64编码器/解码器,似乎至少需要BASE64Decoder,BASE64Encoder,CharacterDecoder,CharacterEncoderCSStreamExhausted,它们都在sun.misc包中。如果我用这些类创建一个jar,并使用该jar作为--patch-module的参数,我可以从您的评论中解码字符串。(但是,对于更复杂的用例,可能需要更多的类。我没有测试那么远)。


但是,我也要注意,正如tgdavies指出的那样,根据规范:https://www.rfc-editor.org/rfc/rfc2045#page-25中的字母表表,您的字符串不是有效的base 64字符串(与MIME编码器/解码器相同的规范)。:是非法的,它被解码器忽略,这意味着末尾用于填充的=会导致问题(您也可以删除末尾的=以获得要解码的字符串)。

我建议尝试清理base 64字符串并使用公共base 64 API。从长远来看,这样做可能会少一些麻烦。

最新更新