java.lang.LinkageError while classloading "com.nimbusds.jwt.JWTClaimsSet"

Hi to all,

I had a normal JavaEE application, which runs just fine with Java 11 and Payara 5.2021.4.

Now I wanted to update to Payara 5.2021.9 and also update Java to version 17 (LTS). But now, the application just starts fine, but if I try to make a first REST call, which involves authentication (where JWT token is involved), I get the attached error.

I checked, that there is no nimbus-jose-jwt library at the application level (because it is provided by Payara in the /modules-directory). Is this a Java 17 think, where classloading-strategy changes? Or is this some Payara thing (again, in 5.2021.4 the application worked without problem), where I need some more configuration?

I would be more than happy, if someone can lead me in the right direction… Many thanks in advance,
Ulrich

javax.ejb.EJBException: loader constraint violation: loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @39cce2b5 wants to load class com.nimbusds.jwt.JWTClaimsSet. A different class with the same name was previously loaded by org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @5db75d5. (com.nimbusds.jwt.JWTClaimsSet is in unnamed module of loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @5db75d5, parent loader java.net.URLClassLoader @4e515669)
	at com.sun.ejb.containers.EJBContainerTransactionManager.processSystemException(EJBContainerTransactionManager.java:723)
	at com.sun.ejb.containers.EJBContainerTransactionManager.completeNewTx(EJBContainerTransactionManager.java:652)
	at com.sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx(EJBContainerTransactionManager.java:482)
	at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4601)
	at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2134)
	at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2104)
	at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:220)
	at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:90)
	at jdk.proxy77/jdk.proxy77.$Proxy332.validateToken(Unknown Source)
...
Caused by: java.lang.LinkageError: loader constraint violation: loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @39cce2b5 wants to load class com.nimbusds.jwt.JWTClaimsSet. A different class with the same name was previously loaded by org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @5db75d5. (com.nimbusds.jwt.JWTClaimsSet is in unnamed module of loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @5db75d5, parent loader java.net.URLClassLoader @4e515669)
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
	at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.defineClass(BundleWiringImpl.java:2332)
	at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.defineClassParallel(BundleWiringImpl.java:2150)
	at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.findClass(BundleWiringImpl.java:2084)
	at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1550)
	at org.apache.felix.framework.BundleWiringImpl.access$300(BundleWiringImpl.java:79)
	at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1970)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	at com.nimbusds.jwt.SignedJWT.getJWTClaimsSet(SignedJWT.java:101)

In addition, after some “mvn clean install, rebooting, referencing nimbus-jose-jwt to version 9.9 in the pom.xml.”, I managed to get the following error message, with is a bit slightly different:

  An exception or error occurred in the container during the request processing
java.lang.LinkageError: loader constraint violation for class fish.payara.security.openid.controller.TokenController$Proxy$_$$_WeldClientProxy: when selecting overriding method 'com.nimbusds.jwt.JWTClaimsSet fish.payara.security.openid.controller.TokenController$Proxy$_$$_WeldClientProxy.validateIdToken(fish.payara.security.openid.domain.IdentityTokenImpl, javax.security.enterprise.authentication.mechanism.http.HttpMessageContext)' the class loader org.glassfish.web.loader.WebappClassLoader @13edbe2f of the selected method's type fish.payara.security.openid.controller.TokenController$Proxy$_$$_WeldClientProxy, and the class loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @14f83eaa for its super type fish.payara.security.openid.controller.TokenController have different Class objects for the type com.nimbusds.jwt.JWTClaimsSet used in the signature (fish.payara.security.openid.controller.TokenController$Proxy$_$$_WeldClientProxy is in unnamed module of loader org.glassfish.web.loader.WebappClassLoader @13edbe2f, parent loader org.glassfish.internal.api.DelegatingClassLoader @20938ee2; fish.payara.security.openid.controller.TokenController is in unnamed module of loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoader @14f83eaa, parent loader java.net.URLClassLoader @4e515669)
	at java.base/java.lang.Class.getDeclaredFields0(Native Method)
	at java.base/java.lang.Class.privateGetDeclaredFields(Class.java:3297)
	at java.base/java.lang.Class.getDeclaredFields(Class.java:2371)
	at org.jboss.weld.bean.proxy.SecurityActions.hasDeclaredField(SecurityActions.java:91)
	at org.jboss.weld.bean.proxy.ProxyFactory.run(ProxyFactory.java:360)
	at org.jboss.weld.bean.proxy.ProxyFactory.create(ProxyFactory.java:351)
	at org.jboss.weld.bean.proxy.ClientProxyFactory.create(ClientProxyFactory.java:83)
	at org.jboss.weld.bean.proxy.ClientProxyProvider.createClientProxy(ClientProxyProvider.java:205)
	at org.jboss.weld.bean.proxy.ClientProxyProvider.createClientProxy(ClientProxyProvider.java:195)
	at org.jboss.weld.bean.proxy.ClientProxyProvider.access$100(ClientProxyProvider.java:44)
	at org.jboss.weld.bean.proxy.ClientProxyProvider$CreateClientProxy.apply(ClientProxyProvider.java:52)
	at org.jboss.weld.bean.proxy.ClientProxyProvider$CreateClientProxy.apply(ClientProxyProvider.java:48)
	at org.jboss.weld.util.cache.ReentrantMapBackedComputingCache.lambda$new$0(ReentrantMapBackedComputingCache.java:55)
	at org.jboss.weld.util.LazyValueHolder$1.computeValue(LazyValueHolder.java:32)
	at org.jboss.weld.util.LazyValueHolder.get(LazyValueHolder.java:46)
	at org.jboss.weld.util.cache.ReentrantMapBackedComputingCache.getValue(ReentrantMapBackedComputingCache.java:72)
	at org.jboss.weld.util.cache.ReentrantMapBackedComputingCache.getCastValue(ReentrantMapBackedComputingCache.java:78)
	at org.jboss.weld.bean.proxy.ClientProxyProvider.getClientProxy(ClientProxyProvider.java:229)
	at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:688)
	at org.jboss.weld.manager.BeanManagerImpl.getInjectableReference(BeanManagerImpl.java:794)
	at org.jboss.weld.injection.FieldInjectionPoint.inject(FieldInjectionPoint.java:92)
	at org.jboss.weld.util.Beans.injectBoundFields(Beans.java:345)
	at org.jboss.weld.util.Beans.injectFieldsAndInitializers(Beans.java:356)
	at org.jboss.weld.injection.producer.ResourceInjector$1.proceed(ResourceInjector.java:69)
	at org.glassfish.weld.services.InjectionServicesImpl.aroundInject(InjectionServicesImpl.java:191)
	at org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:46)
	at org.jboss.weld.injection.producer.ResourceInjector.inject(ResourceInjector.java:71)
	at org.jboss.weld.injection.producer.BasicInjectionTarget.inject(BasicInjectionTarget.java:117)
	at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:161)
	at org.jboss.weld.contexts.AbstractContext.get(AbstractContext.java:96)
	at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.get(ContextualInstanceStrategy.java:100)
	at org.jboss.weld.bean.ContextualInstanceStrategy$ApplicationScopedContextualInstanceStrategy.get(ContextualInstanceStrategy.java:140)
	at org.jboss.weld.bean.ContextualInstance.get(ContextualInstance.java:50)
	at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:102)
	at org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:131)
	at fish.payara.security.openid.OpenIdIdentityStore$Proxy$_$$_WeldClientProxy.validationTypes(Unknown Source)
	at org.glassfish.soteria.cdi.DefaultIdentityStoreHandler.lambda$init$0(DefaultIdentityStoreHandler.java:77)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:178)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
	at org.glassfish.soteria.cdi.DefaultIdentityStoreHandler.init(DefaultIdentityStoreHandler.java:79)
	at org.glassfish.soteria.cdi.CdiExtension.lambda$afterBean$12(CdiExtension.java:239)
	at org.glassfish.soteria.cdi.CdiProducer.create(CdiProducer.java:104)
	at org.jboss.weld.contexts.AbstractContext.get(AbstractContext.java:96)
	at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.get(ContextualInstanceStrategy.java:100)
	at org.jboss.weld.bean.ContextualInstance.get(ContextualInstance.java:50)
	at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:102)
	at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:105)
	at org.jboss.weld.generated.proxiesx.security.enterprise.identitystore.IdentityStoreHandler$1763020431$Proxy$_$$_WeldClientProxy.validate(Unknown Source)
	at fish.payara.microprofile.jwtauth.eesecurity.JWTAuthenticationMechanism.validateRequest(JWTAuthenticationMechanism.java:100)
	at fish.payara.microprofile.jwtauth.eesecurity.JWTAuthenticationMechanism$Proxy$_$$_WeldClientProxy.validateRequest(Unknown Source)
	at org.glassfish.soteria.mechanisms.jaspic.HttpBridgeServerAuthModule.validateRequest(HttpBridgeServerAuthModule.java:151)
	at org.glassfish.soteria.mechanisms.jaspic.DefaultServerAuthContext.validateRequest(DefaultServerAuthContext.java:76)
	at com.sun.web.security.realmadapter.JaspicRealm.validateRequest(JaspicRealm.java:391)
	at com.sun.web.security.realmadapter.JaspicRealm.validateRequest(JaspicRealm.java:358)
	at com.sun.web.security.realmadapter.JaspicRealm.validateRequest(JaspicRealm.java:181)
	at com.sun.web.security.RealmAdapter.invokeAuthenticateDelegate(RealmAdapter.java:487)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:468)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:726)
	at org.apache.catalina.core.StandardPipeline.doChainInvoke(StandardPipeline.java:581)
	at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:158)
	at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
	at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:520)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:217)
	at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:182)
	at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:156)
	at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:218)
	at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:95)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:260)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:177)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:109)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:88)
	at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:53)
	at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:524)
	at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:89)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:94)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:33)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:114)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:569)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:549)
	at java.base/java.lang.Thread.run(Thread.java:833)
]]

ADDITIONAL HINT: The problem was introduced since in Payara 5.2021.6 (all versions lower than this version work well, from version 5.2021.6 up to 5.2021.9), the error occurs.

Hi, if this happens also on Java 11, it looks like a bug in Payara Server introduced in 5.2021.6. In that case please raise an issue on Github (Issues · payara/Payara · GitHub) with a simple reproducer that demonstrates the error on Payara Server 5.2021.9 (the latest version of Payara).

All the best,
Ondro

Hi Ondro,

alright, I pushed a “reproducer project” to GitHub and opened an issue:

It has something to do with the javax.ws.rs.container.ContainerRequestFilter, which seems to be loaded in another classloader, which causes the error.

Bye, Ulrich

Hi, Ulrich,

Thanks for raising the issue with a useful reproducer. It seems that Payara Server 5.2021.6 and newer contains duplicate nimbus classes, in 2 different modules, which shouldn’t happen. We’ll address the issue soon.

All the best,
Ondro

1 Like