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

Reflection access problems with 0.12.0 on JDK 17+ #849

Closed
unrealwork opened this issue Oct 4, 2023 · 10 comments · Fixed by #852
Closed

Reflection access problems with 0.12.0 on JDK 17+ #849

unrealwork opened this issue Oct 4, 2023 · 10 comments · Fixed by #852
Labels
Milestone

Comments

@unrealwork
Copy link

Hi @lhazlewood, thank you for your hard work during this release.
I've had some problems using the new API. I tried to sign a JWT token using Jwts.SIG.RS256 algo and got io.jsonwebtoken.security.SignatureException.

Environment

JDK: 17

java version "17.0.7" 2023-04-18 LTS
Java(TM) SE Runtime Environment Oracle GraalVM 17.0.7+8.1 (build 17.0.7+8-LTS-jvmci-23.0-b12)
Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 17.0.7+8.1 (build 17.0.7+8-LTS-jvmci-23.0-b12, mixed mode, sharing)

Version: 0.12.0

Minimal test to reproduce

@Test
void testRs256Signing() {
    KeyPair kp = Jwts.SIG.RS256.keyPair().build();
    Jwts.builder()
            .signWith(kp.getPrivate(), Jwts.SIG.RS256)
            .compact();
}

Result

io.jsonwebtoken.security.SignatureException: Unable to compute RS256 signature with JCA algorithm 'SHA256withRSA' using key {class: sun.security.rsa.RSAPrivateCrtKeyImpl, algorithm: RSA, format: PKCS#8}: Reflection operation failed. This is likely due to an internal implementation programming error. Please report this to the JJWT development team. Cause: class io.jsonwebtoken.impl.lang.OptionalMethodInvoker cannot access class sun.security.util.KeyUtil (in module java.base) because module java.base does not export sun.security.util to unnamed module @66d33a

Stacktrace
io.jsonwebtoken.security.SignatureException: Unable to compute RS256 signature with JCA algorithm 'SHA256withRSA' using key {class: sun.security.rsa.RSAPrivateCrtKeyImpl, algorithm: RSA, format: PKCS#8}: Reflection operation failed. This is likely due to an internal implementation programming error.  Please report this to the JJWT development team.  Cause: class io.jsonwebtoken.impl.lang.OptionalMethodInvoker cannot access class sun.security.util.KeyUtil (in module java.base) because module java.base does not export sun.security.util to unnamed module @66d33a
  at io.jsonwebtoken.impl.security.AbstractSecureDigestAlgorithm.digest(AbstractSecureDigestAlgorithm.java:54)
  at io.jsonwebtoken.impl.security.AbstractSecureDigestAlgorithm.digest(AbstractSecureDigestAlgorithm.java:29)
  at io.jsonwebtoken.impl.DefaultJwtBuilder$1.apply(DefaultJwtBuilder.java:246)
  at io.jsonwebtoken.impl.DefaultJwtBuilder$1.apply(DefaultJwtBuilder.java:243)
  at io.jsonwebtoken.impl.lang.DelegatingCheckedFunction.apply(DelegatingCheckedFunction.java:28)
  at io.jsonwebtoken.impl.lang.PropagatingExceptionFunction.apply(PropagatingExceptionFunction.java:57)
  at io.jsonwebtoken.impl.DefaultJwtBuilder.sign(DefaultJwtBuilder.java:622)
  at io.jsonwebtoken.impl.DefaultJwtBuilder.compact(DefaultJwtBuilder.java:534)
  at com.guavapay.cardium.cpg.order.app.service.OrderSessionTokenServiceTest.testMini(OrderSessionTokenServiceTest.java:54)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.base/java.lang.reflect.Method.invoke(Method.java:568)
  at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
  at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
  at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
  at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
  at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
  at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
  at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
  at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
  at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
  at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
  at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
  at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
  at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
  at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
  at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
  at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
  at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
  at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
  at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
  at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
  at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
  at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
  at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
  at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
  at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
  at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.base/java.lang.reflect.Method.invoke(Method.java:568)
  at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
  at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
  at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
  at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
  at jdk.proxy2/jdk.proxy2.$Proxy5.stop(Unknown Source)
  at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
  at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
  at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
  at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
  at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
  at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
  at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
  at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
  at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: java.lang.IllegalStateException: Reflection operation failed. This is likely due to an internal implementation programming error.  Please report this to the JJWT development team.  Cause: class io.jsonwebtoken.impl.lang.OptionalMethodInvoker cannot access class sun.security.util.KeyUtil (in module java.base) because module java.base does not export sun.security.util to unnamed module @66d33a
  at io.jsonwebtoken.impl.lang.ReflectionFunction.apply(ReflectionFunction.java:35)
  at io.jsonwebtoken.impl.security.KeysBridge.findBitLength(KeysBridge.java:116)
  at io.jsonwebtoken.impl.security.RsaSignatureAlgorithm.validateKey(RsaSignatureAlgorithm.java:186)
  at io.jsonwebtoken.impl.security.AbstractSecureDigestAlgorithm.digest(AbstractSecureDigestAlgorithm.java:47)
  ... 94 more
Caused by: java.lang.IllegalAccessException: class io.jsonwebtoken.impl.lang.OptionalMethodInvoker cannot access class sun.security.util.KeyUtil (in module java.base) because module java.base does not export sun.security.util to unnamed module @66d33a
  at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:392)
  at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:674)
  at java.base/java.lang.reflect.Method.invoke(Method.java:560)
  at io.jsonwebtoken.impl.lang.OptionalMethodInvoker.invoke(OptionalMethodInvoker.java:62)
  at io.jsonwebtoken.impl.lang.ReflectionFunction.apply(ReflectionFunction.java:31)
  ... 97 more


Reflection operation failed. This is likely due to an internal implementation programming error.  Please report this to the JJWT development team.  Cause: class io.jsonwebtoken.impl.lang.OptionalMethodInvoker cannot access class sun.security.util.KeyUtil (in module java.base) because module java.base does not export sun.security.util to unnamed module @66d33a
java.lang.IllegalStateException: Reflection operation failed. This is likely due to an internal implementation programming error.  Please report this to the JJWT development team.  Cause: class io.jsonwebtoken.impl.lang.OptionalMethodInvoker cannot access class sun.security.util.KeyUtil (in module java.base) because module java.base does not export sun.security.util to unnamed module @66d33a
  at io.jsonwebtoken.impl.lang.ReflectionFunction.apply(ReflectionFunction.java:35)
  at io.jsonwebtoken.impl.security.KeysBridge.findBitLength(KeysBridge.java:116)
  at io.jsonwebtoken.impl.security.RsaSignatureAlgorithm.validateKey(RsaSignatureAlgorithm.java:186)
  at io.jsonwebtoken.impl.security.AbstractSecureDigestAlgorithm.digest(AbstractSecureDigestAlgorithm.java:47)
  at io.jsonwebtoken.impl.security.AbstractSecureDigestAlgorithm.digest(AbstractSecureDigestAlgorithm.java:29)
  at io.jsonwebtoken.impl.DefaultJwtBuilder$1.apply(DefaultJwtBuilder.java:246)
  at io.jsonwebtoken.impl.DefaultJwtBuilder$1.apply(DefaultJwtBuilder.java:243)
  at io.jsonwebtoken.impl.lang.DelegatingCheckedFunction.apply(DelegatingCheckedFunction.java:28)
  at io.jsonwebtoken.impl.lang.PropagatingExceptionFunction.apply(PropagatingExceptionFunction.java:57)
  at io.jsonwebtoken.impl.DefaultJwtBuilder.sign(DefaultJwtBuilder.java:622)
  at io.jsonwebtoken.impl.DefaultJwtBuilder.compact(DefaultJwtBuilder.java:534)
  at com.guavapay.cardium.cpg.order.app.service.OrderSessionTokenServiceTest.testMini(OrderSessionTokenServiceTest.java:54)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.base/java.lang.reflect.Method.invoke(Method.java:568)
  at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
  at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
  at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
  at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
  at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
  at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
  at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
  at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
  at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
  at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
  at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
  at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
  at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
  at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
  at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
  at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
  at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
  at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
  at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
  at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
  at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
  at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
  at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
  at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
  at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
  at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
  at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
  at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
  at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
  at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
  at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
  at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.base/java.lang.reflect.Method.invoke(Method.java:568)
  at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
  at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
  at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
  at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
  at jdk.proxy2/jdk.proxy2.$Proxy5.stop(Unknown Source)
  at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
  at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
  at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
  at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
  at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
  at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
  at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
  at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
  at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: java.lang.IllegalAccessException: class io.jsonwebtoken.impl.lang.OptionalMethodInvoker cannot access class sun.security.util.KeyUtil (in module java.base) because module java.base does not export sun.security.util to unnamed module @66d33a
  at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:392)
  at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:674)
  at java.base/java.lang.reflect.Method.invoke(Method.java:560)
  at io.jsonwebtoken.impl.lang.OptionalMethodInvoker.invoke(OptionalMethodInvoker.java:62)
  at io.jsonwebtoken.impl.lang.ReflectionFunction.apply(ReflectionFunction.java:31)
  ... 97 more
@lhazlewood
Copy link
Contributor

@unrealwork thanks so much for opening this issue.

Unfortunately this is due to the Java 9+ module system not liking reflection. As a workaround, you'll have to add the following to your build and/or app configuration:

--add-opens java.base/sun.security.util=ALL-UNNAMED

I'm unaware of what other --add-opens must be added for JDK 17 for your particular use case, but I'll use this ticket to capture the work related to figuring this out so we can avoid these workarounds. I'll try to address it in a followup release (e.g. 0.12.1) as soon as possible.

@unrealwork
Copy link
Author

@lhazlewood Yeah, I got it. It works with --add-exports java options. But maybe you could come up with a more elegant solution inside the library. I'll try to use suggested --add-opens. Appreciate your quick feedback.

test {
    jvmArgs("--add-exports", "java.base/sun.security.util=ALL-UNNAMED")
}

@lhazlewood
Copy link
Contributor

lhazlewood commented Oct 4, 2023

@unrealwork I found these three allowed me to run the JavaReadmeTest:

--add-opens java.base/java.lang=ALL-UNNAMED,
--add-opens java.base/java.io=ALL-UNNAMED,
--add-opens java.base/sun.security.util=ALL-UNNAMED

I'll try to find a native/automatic solution for this as soon as possible. Thanks again!

@patton73
Copy link
Contributor

patton73 commented Oct 4, 2023

Yes please a fix is needed. It should be fully compatible with java 9+. The version 0.11.5 is.

@OleksandrShkurat
Copy link

I've got a similar issue (JDK 17.0.7):

...
Caused by: io.jsonwebtoken.io.DecodingException: Unable to Base64Url-decode InputStream: Unable to read field java.io.ByteArrayInputStream#buf: Unable to make field protected byte[] java.io.ByteArrayInputStream.buf accessible: module java.base does not "opens java.io" to unnamed module @2a225dd7
	at app//io.jsonwebtoken.impl.io.DelegateStringDecoder.decode(DelegateStringDecoder.java:44)
	at app//io.jsonwebtoken.impl.io.DelegateStringDecoder.decode(DelegateStringDecoder.java:26)
	at app//io.jsonwebtoken.impl.DefaultJwtParser.decode(DefaultJwtParser.java:877)
	... 12 more
Caused by: java.lang.IllegalStateException: Unable to read field java.io.ByteArrayInputStream#buf: Unable to make field protected byte[] java.io.ByteArrayInputStream.buf accessible: module java.base does not "opens java.io" to unnamed module @2a225dd7
	at io.jsonwebtoken.lang.Classes.getFieldValue(Classes.java:352)
	at io.jsonwebtoken.impl.io.Streams.bytes(Streams.java:47)
	at io.jsonwebtoken.impl.io.DelegateStringDecoder.decode(DelegateStringDecoder.java:39)
	... 14 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field protected byte[] java.io.ByteArrayInputStream.buf accessible: module java.base does not "opens java.io" to unnamed module @2a225dd7
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
	at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
	at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
	at io.jsonwebtoken.lang.Classes.getFieldValue(Classes.java:346)
	... 16 more

I don't like the idea of 'hacking' a JVM. Seems, I'd better postpone the upgrade of jjwt 0.11.5 to more recent version until this issues is fixed.

@donalmurtagh
Copy link

donalmurtagh commented Oct 4, 2023

I ran into this issue when using the HmacSHA512 algorithm with v. 0.12.0. The same problem occurs regardless of whether I use the new APIs or the APIs that are deprecated in v. 0.12.0.

Here's a test case for both APIs

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.junit.jupiter.api.Test;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.Map;

import static java.nio.charset.StandardCharsets.UTF_8;

public class JwtTests {
    private final byte[] secret = "?Ka}SqPl][^s*(dFerF]fEOpz#F~4P.x{/|#0!NtvlYUhW(hun2TQt}3+'f{|A8t:z7QzI_E:{^6bv".getBytes(UTF_8);

    @Test
    void generateSignedJwt_V_0_12() {
        var signingKey = Keys.hmacShaKeyFor(secret);
        LocalDateTime tokenExpirationTime = LocalDateTime.now().plusMinutes(15);

        Jwts.builder()
            .signWith(signingKey, Jwts.SIG.HS512)
            .header().add("typ", "JWT").and()
            .issuer("secure-api")
            .audience().add("secure-app").and()
            .subject("foo@bar.com")
            .expiration(Timestamp.valueOf(tokenExpirationTime))
            .claims(Map.of("key", "value"))
            .compact();
    }

    @Test
    void generateSignedJwt_V_0_11_5() {
        var signingKey = Keys.hmacShaKeyFor(secret);
        LocalDateTime tokenExpirationTime = LocalDateTime.now().plusMinutes(15);

        Jwts.builder()
            .signWith(signingKey, SignatureAlgorithm.HS512)
            .setHeaderParam("typ", "JWT")
            .setIssuer("secure-api")
            .setAudience("secure-app")
            .setSubject("foo@bar.com")
            .setExpiration(Timestamp.valueOf(tokenExpirationTime))
            .addClaims(Map.of("key", "value"))
            .compact();
    }
}

In both cases, the test fails under version 0.12.0 with the following exception

io.jsonwebtoken.security.SignatureException: Unable to compute HS512 signature with JCA algorithm 'HmacSHA512' using key {class: javax.crypto.spec.SecretKeySpec, algorithm: HmacSHA512, format: RAW}: Reflection operation failed. This is likely due to an internal implementation programming error.  Please report this to the JJWT development team.  Cause: class io.jsonwebtoken.impl.lang.OptionalMethodInvoker cannot access class sun.security.util.KeyUtil (in module java.base) because module java.base does not export sun.security.util to unnamed module @be68757
	at io.jsonwebtoken.impl.security.AbstractSecureDigestAlgorithm.digest(AbstractSecureDigestAlgorithm.java:54)
	at io.jsonwebtoken.impl.security.AbstractSecureDigestAlgorithm.digest(AbstractSecureDigestAlgorithm.java:29)
	at io.jsonwebtoken.impl.DefaultJwtBuilder$1.apply(DefaultJwtBuilder.java:246)
	at io.jsonwebtoken.impl.DefaultJwtBuilder$1.apply(DefaultJwtBuilder.java:243)
	at io.jsonwebtoken.impl.lang.DelegatingCheckedFunction.apply(DelegatingCheckedFunction.java:28)
	at io.jsonwebtoken.impl.lang.PropagatingExceptionFunction.apply(PropagatingExceptionFunction.java:57)
	at io.jsonwebtoken.impl.DefaultJwtBuilder.sign(DefaultJwtBuilder.java:622)
	at io.jsonwebtoken.impl.DefaultJwtBuilder.compact(DefaultJwtBuilder.java:534)

The second test case generateSignedJwt_V_0_11_5 passes when run under version 0.11.5. I'm using JDK 17.

@lhazlewood
Copy link
Contributor

@donalmurtagh the cause is in the exception message:

because module java.base does not export sun.security.util to unnamed module @be68757

Try adding the corresponding --add-opens flag and that should solve this issue for you until we can determine a fix for this.

@lhazlewood lhazlewood added the JPMS label Oct 4, 2023
@lhazlewood lhazlewood changed the title Reflection access error during RS256 signing Reflection access problems with 0.12.0 Oct 4, 2023
@lhazlewood lhazlewood changed the title Reflection access problems with 0.12.0 Reflection access problems with JJWT 0.12.0 on JDK 17+ Oct 4, 2023
@lhazlewood lhazlewood changed the title Reflection access problems with JJWT 0.12.0 on JDK 17+ Reflection access problems with 0.12.0 on JDK 17+ Oct 5, 2023
lhazlewood added a commit that referenced this issue Oct 5, 2023
- enabled reflective access to `java.io.ByteArrayInputStream` and `sun.misc.security.KeyUtil` on JDK 17+
- Minor refactor to ServicesTest to avoid the need for PowerMock
@lhazlewood lhazlewood mentioned this issue Oct 5, 2023
@lhazlewood lhazlewood added this to the 0.12.1 milestone Oct 5, 2023
lhazlewood added a commit that referenced this issue Oct 5, 2023
- enabled reflective access to `java.io.ByteArrayInputStream` and `sun.misc.security.KeyUtil` on JDK 17+
- Minor refactor to ServicesTest to avoid the need for PowerMock
@lhazlewood
Copy link
Contributor

Hi folks, this has been resolved and released in 0.12.1. Please allow 30 minutes from the time of this post for the release to be in Maven Central.

If anyone has any other issues, please do let us know by opening a new issue/ticket. Thank you!

@lhazlewood
Copy link
Contributor

The 0.12.1 release only addressed projects that did not have a module-info.java and failed for those that did. 0.12.2 has been released and should work in all projects now.

@donalmurtagh
Copy link

v. 0.12.2 fixes the problem for me, thanks @lhazlewood for resolving this so quickly

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.

5 participants