由于各种原因,我需要继续使用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
,CharacterEncoder
和CSStreamExhausted
,它们都在sun.misc
包中。如果我用这些类创建一个jar,并使用该jar作为--patch-module
的参数,我可以从您的评论中解码字符串。(但是,对于更复杂的用例,可能需要更多的类。我没有测试那么远)。
但是,我也要注意,正如tgdavies指出的那样,根据规范:https://www.rfc-editor.org/rfc/rfc2045#page-25中的字母表表,您的字符串不是有效的base 64字符串(与MIME编码器/解码器相同的规范)。:
是非法的,它被解码器忽略,这意味着末尾用于填充的=
会导致问题(您也可以删除末尾的=
以获得要解码的字符串)。
我建议尝试清理base 64字符串并使用公共base 64 API。从长远来看,这样做可能会少一些麻烦。