Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
FreEZer00 opened this issue Oct 5, 2023 · 5 comments · Fixed by #855
Assignees
Labels
Milestone

Comments

@FreEZer00
Copy link

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

@lhazlewood
Copy link
Contributor

@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.

@lhazlewood lhazlewood added this to the 0.12.2 milestone Oct 5, 2023
@lhazlewood lhazlewood self-assigned this Oct 5, 2023
@lhazlewood
Copy link
Contributor

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!

@stasim101
Copy link

stasim101 commented Oct 5, 2023

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

@lhazlewood
Copy link
Contributor

@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

lhazlewood added a commit that referenced this issue Oct 6, 2023
- Replaced ByteArrayInputStream reflection with new BytesInputStream implementation. The reflection is what required --add-opens java.base/java.io=jjwt.api on JDK 17.
lhazlewood added a commit that referenced this issue Oct 6, 2023
- Replaced ByteArrayInputStream reflection with new BytesInputStream implementation. The reflection is what required --add-opens java.base/java.io=jjwt.api on JDK 17+.
- Refactored KeysBridge to perform our own key length logic instead of delegating to sun.security.util.KeyUtil.  The reflection is what required --add-opens java.base/sun.security.util=jjwt.api on JDK 17+
- Removed AddOpens.java due to above refactoring (no longer needed).
lhazlewood added a commit that referenced this issue Oct 6, 2023
- Replaced ByteArrayInputStream reflection with new BytesInputStream implementation. The reflection is what required --add-opens java.base/java.io=jjwt.api on JDK 17+.
- Refactored KeysBridge to perform our own key length logic instead of delegating to sun.security.util.KeyUtil.  The reflection is what required --add-opens java.base/sun.security.util=jjwt.api on JDK 17+
- Removed AddOpens.java due to above refactoring (no longer needed).
- Returned a test-only --add-opens for sun.security.util for 3 test cases (added to test.addOpens maven property)
lhazlewood added a commit that referenced this issue Oct 6, 2023
* Closes #854.

- Replaced `ByteArrayInputStream` reflection with new `BytesInputStream` implementation. The reflection is what required `--add-opens java.base/java.io=jjwt.api` on JDK 17+.
- Refactored `KeysBridge` to perform our own key length logic instead of delegating to `sun.security.util.KeyUtil`.  The reflection is what required `--add-opens java.base/sun.security.util=jjwt.api` on JDK 17+
- Removed `AddOpens.java` due to above refactoring (no longer needed).
- Returned a test-only `--add-opens` for `sun.security.util` for 3 test cases (added to `test.addOpens` maven property)
@lhazlewood
Copy link
Contributor

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

@lhazlewood lhazlewood added the JPMS label Oct 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants