Home > other >  Patch jdk.unsupported module in Java 17
Patch jdk.unsupported module in Java 17

Time:12-09

For various reasons, I need to continue to use some sun.misc classes in Java 17, specifically the BASE64Decoder class. (The algorithm used by the class has some specific behavior that other base 64 decoders do not reproduce.) I'm planning to use the rt.jar file, provided in OpenJDK 8, as the source for these classes, and I'm patching the jdk.unsupported module.

With the following example class, I'm able to compile it using 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]));
  }
}

It seems that in versions of Java prior to Java 17, it was possible to then run it with patch-module:

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

However, in Java 17, this fails with java.lang.module.ResolutionException: Module jdk.unsupported contains package java.time.zone, module java.base exports package java.time.zone to jdk.unsupported. It seems like since java.base exports to jdk.unsupported, it's not possible to patch the jdk.unsupported module. Is there any way to work around this?

Versions:

$ 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

(The Java 11 version of this question is Why is the Java 11 runtime ignoring my jar containing sun.misc classes?, this is not a duplicate of that question.)

CodePudding user response:

As mentioned in the comments, the problem is split packages. i.e. you can't have 2 modules that define the same package (java.time.zone in this case).

If you want to go the --patch-module route, you can not use the whole rt.jar. You will have to create a jar file with just classes in sun.misc that you need.

For the base 64 encoder/decoder, it seems that at least BASE64Decoder, BASE64Encoder, CharacterDecoder, CharacterEncoder, and CSStreamExhausted are needed, all in the sun.misc package. If I create a jar with just those classes, and use that jar as an argument to --patch-module, I'm able to decode the string from your comment. (but, more classes might be needed for a more complex use case. I didn't test that far).


But, I'll also note that, as tgdavies pointed out, your string is not a valid base 64 string, according to the alphabet table in the spec: https://www.rfc-editor.org/rfc/rfc2045#page-25 (the same spec followed by the MIME encoder/decoder). The : is illegal, and it is ignored by the decoder, which means the trailing = used for padding is causing issue (you can also remove the = at the end to get the string to decode).

I'd recommend trying to sanitize your base 64 string and using the public base 64 API. That will probably be less of a hassle to keep working in the long term.

  • Related