jwtk/jjwt

java.lang.reflect.InaccessibleObjectException when using parseUnsecuredClaims() v0.12.1 Java 17

FreEZer00 opened this issue · 5 comments

Describe the bug
Currently when trying to upgrade to the latest release the method parseUnsecuredClaims throws an InaccessibleObjectException.
v0.12.1 Java 17

To Reproduce
Steps to reproduce the behavior:

  1. Create parser using: Jwts.parser().build();
  2. Attempt to parse: jwtParser.parseUnsecuredClaims(jwtString)
  3. See error: Unable to make field protected byte[] java.io.ByteArrayInputStream.buf accessible: module java.base does not "opens java.io" to unnamed module @4f933fd1

Exception thrown in io.jsonwebtoken.lang.Classes line 346

Expected behavior
JWT parsed successfully and claims are returned properly

@FreEZer00 , I see, thank you. It seems as if our edit yesterday was placed 'too late' during class initialization for certain use cases. I'll see about getting a follow-up release out today that initializes sooner, in the appropriate place.

So I ran a test in a completely separate project/jvm using this test class:

package test;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Header;
import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.Jwts;

public class Main {

    public static void main(String[] args) {
        String token = "eyJhbGciOiJub25lIn0.eyJzdWIiOiJKb2UifQ.";
        Jwt<Header, Claims> jwt = Jwts.parser().unsecured().build().parseUnsecuredClaims(token);
        System.out.println("jwt: " + jwt);
    }
}

When there is no module-info.java file in that same project, everything works as expected. Adding the following module-info.java file:

module JJWT.Standalone.Test {
    requires jjwt.api;
}

will result in the test failing.

I'm digging in now to see if there's an easy enough workaround. Thank you again for reporting the issue!

The policies of reflection have changed since JDK 9. I tried running it on JDK 8, it worked well. Later on JDK 17, you need to pass these JVM Arguments while deploying your application.

--add-opens=java.base/java.lang=ALL-UNNAMED

For JDK17 reference: https://confluence.atlassian.com/jiracore/java-17-runtime-opens-and-exports-arguments-1188413810.html

@stasim101 correct, but you don't need to open that up for all modules, if you do have a module-info.java file for your project (like the one shown above), you can expose it to just JJWT via:

--add-opens java.base/java.io=jjwt.api

Resolved in the 0.12.2 release (no more --add-opens for JJWT).