Skip to content

Fix a race condition that leads to ClassAnalyzer with name CdiInjecteeSkippingClassAnalyzer exceptions#6049

Merged
arjantijms merged 3 commits into
eclipse-ee4j:4.xfrom
OmniFish-EE:ondromih-2026-01-ClassAnalyzer-race-condition-pr
Jan 14, 2026
Merged

Fix a race condition that leads to ClassAnalyzer with name CdiInjecteeSkippingClassAnalyzer exceptions#6049
arjantijms merged 3 commits into
eclipse-ee4j:4.xfrom
OmniFish-EE:ondromih-2026-01-ClassAnalyzer-race-condition-pr

Conversation

@OndroMih

Copy link
Copy Markdown
Contributor

This solves the race condition - keep the effective injectionManager in a thread local. As multiple threads can modify the injectionManager and the InjectionManagerInjectedCdiTarget instances are global, effectiveInjectionManager must be scoped to the thread. It's actually scoped to a single WebTarget initialization and removed at the end of the initialization in the done() method of CdiComponentProvider

The problem:

A race condition happens when many threads execute REST client call at the same (more specifically, when WebTarget.request() is called.

Symptom:

Occasional
IllegalStateException: Could not find an implementation of ClassAnalyzer with name CdiInjecteeSkippingClassAnalyzer from WebTarget.request

Reason for the exception:

  • The injectionManager is set in the initialization phase, before it's used. It's stored to a shared volatile variable and later picked up
  • If some thread sets the shared volatile variable to another injectionManager, before the original thread uses it, the original thread would use another thread's injectionManager
  • In case the second thread doesn't bind the ClassAnalyzer class in time before the first thread uses it, the first thread won't have ClassAnalyzer bean available and throws exception

A reproducer is described in payara/Payara#7753.

The original fix in Payara fork (53ae843) addresses this by a workaround - a retry in case of exception, which works, because by the next time, the other thread has enough time to bind the ClassAnalyzer class. But that solution isn't efficient.

Happens when many threads execute REST client call at the same.

Symptom:

Occasional 
IllegalStateException: Could not find an implementation of ClassAnalyzer with name CdiInjecteeSkippingClassAnalyzer
from WebTarget.request

Reason for the exception:
* The injectionManager is set earlier than it's used, it's stored to a shared volatile variable and later picked up
* If some thread sets the shared volatile variable to another injectionManager, the original thread would use another threads injectionManager
* In case the second thread doesn't bind the ClassAnalyzer class in time before the first thread uses it, the first thread won't have ClassAnalyzer bean available and throws exception
@OndroMih

Copy link
Copy Markdown
Contributor Author

Hi, @jansupol , @Verdent , could you please review and approve if OK?

@jansupol

Copy link
Copy Markdown
Contributor

@OndroMih
Would it be performance better (for many threads) if the ThreadLocal would be in each InjectionManagerInjectedCdiTarget?

@OndroMih

OndroMih commented Jan 12, 2026

Copy link
Copy Markdown
Contributor Author

@jansupol , I wanted to set the threadlocal in each target instance initially. But I didn’t find a nice way to access all targets from done method to remove the thread locals. Having the thread local in the top-level instance is easier because it can be accessed both from the done method and from all targets directly.

The targets are not directly accessible from their top-level class, if I’m not wrong. They are referenced from a store, which only supports setting injection manager. I would have to adjust the store contract to somehow allow removing the thread locals from all targets. Do you have an idea how to do it? Is it worth it?

@OndroMih

Copy link
Copy Markdown
Contributor Author

@jansupol , maybe for a better performance, targets could set the thread local only if it's not set already. I read that ThreadLocal.get is faster than ThreadLocal.set, even if setting the same value that it already contains.

Within a single invocation, the injection manager would always be the same so with the current change, the first target sets the ThreadLocal value and all others just set it again to the same value. If they call get instead, it could be faster.

@OndroMih
OndroMih marked this pull request as draft January 13, 2026 16:38
@OndroMih

Copy link
Copy Markdown
Contributor Author

By trying that, I found out that the done method is not call on the instance of CdiComponentProvider which holds the targets. The done method is called on a completely different CdiComponentProvider, therefore a different thread local is removed, a one that contains null value and not an injectionManager.

It looks like CdiComponentProvider that contains the targets, is global to the application and shared by different REST client invocations.

I struggle to find out a good way to remove the thread local, I don't know how to get the correct instance of CdiComponentProvider in the done method, which is called from a REST client request.

@OndroMih

Copy link
Copy Markdown
Contributor Author

I found the correct component that holds the thread local. It's the same extension which is used in the initialize method. Now the code removes the previously set thread local. And setting the thread local only if it's not already set also works.

@OndroMih
OndroMih marked this pull request as ready for review January 13, 2026 17:36
@OndroMih
OndroMih force-pushed the ondromih-2026-01-ClassAnalyzer-race-condition-pr branch from 3ad72df to d768a3c Compare January 13, 2026 19:46
Remove the thread local from the correct component (same as retrieved in the CdiComponentProvider.initialize method)

Save a few nanoseconds by calling get instead of set on the thread local, log an error if a leaking injectionManager detected.
@OndroMih
OndroMih force-pushed the ondromih-2026-01-ClassAnalyzer-race-condition-pr branch from d768a3c to dceaeaf Compare January 13, 2026 21:24
@OndroMih

Copy link
Copy Markdown
Contributor Author

A tested detected a leak - in some cases, ClientRuntime initializes CdiComponentProvider again, after postInit, without calling done later.

My solution is a bit hacky - move postInit for ClientComponentConfigurator to after ClientRuntime is created to properly clean up the thread local, while keep calling postInit for other configurators before ClientRuntime is created, because ClientRuntime depends on recourses set up in other configurators.

ClientComponentConfigurator only cleans up resources in postInit, so it's OK to call it later.

The initRuntime method already treats messageBodyWorkersConfigurator in a special way, so I think it's OK to add a special treatment also for ClientComponentConfigurator.

Another solution that also works would be to call postInit on ClientComponentConfigurator twice, at the same place as before, with all other configurator, and once again after ClientRuntime is created. But I didn't want to call it twice.

Yet another solution would be to add a special method to ClientComponentConfigurator, e.g. cleanup(), but that would introduce a few more changes - ClientComponentConfigurator delegates to multiple ComponentProvider instances. So I would need to add another default NoOp cleanup method to the ComponentProvider interface and another cleanup method to CdiComponentProvider to remove the thread local.

The code in ClientConfig would then look like before, with just another call to:

preInit.clientComponentConfigurator.cleanup(injectionManager, preInit.bootstrapBag);

Or if I also add a default NoOp method to BootstrapConfigurator interface, we could make it more general (the cleanup method would be called for all configurators, just as the postInit method is called earlier):

bootstrapConfigurators.forEach(configurator -> configurator.cleanup(injectionManager, preInit.bootstrapBag));

All of these solutions would work equally. The questions is which solution is better?

What do you think, @jansupol , @senivam ?

Is it better to treat the ClientComponentConfigurator specially and call postInit for it later than for other components? (my current solution)

Or is it better to call postInit as before, and add cleanup method to cleanup resources?

@OndroMih
OndroMih force-pushed the ondromih-2026-01-ClassAnalyzer-race-condition-pr branch 3 times, most recently from 111af26 to faeee7a Compare January 14, 2026 09:46
If ClientRuntime needs CDI beans, it initializes CdiComponentProvider again, we need to clean up later.
@OndroMih
OndroMih force-pushed the ondromih-2026-01-ClassAnalyzer-race-condition-pr branch from faeee7a to 6189f01 Compare January 14, 2026 11:54
@OndroMih
OndroMih requested a review from senivam January 14, 2026 13:31
@arjantijms
arjantijms deleted the branch eclipse-ee4j:4.x January 14, 2026 19:38
@arjantijms arjantijms closed this Jan 14, 2026
@arjantijms arjantijms reopened this Jan 14, 2026
@arjantijms
arjantijms changed the base branch from 4.0 to 4.x January 14, 2026 20:18
@arjantijms
arjantijms merged commit bfa2b55 into eclipse-ee4j:4.x Jan 14, 2026
16 of 17 checks passed
@breakponchito

breakponchito commented Jun 26, 2026

Copy link
Copy Markdown

@OndroMih Can this be replicated to Jersey 3.x, I replicated the issue using Glassfish 7.1.0 and I saw that is using Jersey version 3.1.11, also I tried with Glassfish 5 to test jersey version 2.x but in this case was not possible to replicate. Here part of the log:

[2026-06-25T19:42:11.043412-06:00] [GF 7.1.0] [WARNING] [] [org.glassfish.jersey.internal.Errors] [tid: _ThreadID=135 _ThreadName=http-listener-1(4)] [levelValue: 900] [[
  The following warnings have been detected: WARNING: HK2 failure has been detected in a code that does not run in an active Jersey Error scope.
WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 1
java.lang.IllegalStateException: Could not find an implementation of ClassAnalyzer with name CdiInjecteeSkippingClassAnalyzer
	at org.jvnet.hk2.internal.ServiceLocatorImpl.getAnalyzer(ServiceLocatorImpl.java:2500)
	at org.jvnet.hk2.internal.Utilities.getClassAnalyzer(Utilities.java:145)
	at org.jvnet.hk2.internal.Utilities.justInject(Utilities.java:971)
	at org.jvnet.hk2.internal.ServiceLocatorImpl.inject(ServiceLocatorImpl.java:1026)
	at org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.inject(AbstractHk2InjectionManager.java:217)
	at org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager.inject(ImmediateHk2InjectionManager.java:30)
	at org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider$InjectionManagerInjectedCdiTarget.inject(CdiComponentProvider.java:679)
	at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:165)

And do you think it is good to also include on Jersey 2.x?

@OndroMih

Copy link
Copy Markdown
Contributor Author

I think it’s OK for 3.1 branch. I’m not a Jersey committer but the Jersey team is active and some of my colleagues are in the team.

Would you raise a PR for Jersey 3.1 branch with a port of the fix?

if you’d like to port and release a fix also in the 2.x branch, ask committers from Oracle. OmniFish doesn’t maintain the 2.x but I saw some activity from Oracle on that branch, probably related to WebLogic.

@breakponchito

Copy link
Copy Markdown

I think it’s OK for 3.1 branch. I’m not a Jersey committer but the Jersey team is active and some of my colleagues are in the team.

Would you raise a PR for Jersey 3.1 branch with a port of the fix?

if you’d like to port and release a fix also in the 2.x branch, ask committers from Oracle. OmniFish doesn’t maintain the 2.x but I saw some activity from Oracle on that branch, probably related to WebLogic.

yes I will create the PR porting your fix to version 3.x

@lprimak

lprimak commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

I am sorry to report that this fix introduced a ClassLoader leak.

See payara/Payara#8260

@OndroMih

OndroMih commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

I’m not sure how this can lead to the leak you described in the Payara issue. This change only impacts WebTarget - Jersey Client, not server. I don’t see any Jersey client usage in your reproducer.

@lprimak

lprimak commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

I am not sure either :) But the new code is clearly failing, the logs and the VisualVM screenshots prove it.
Isn't CdiComponentProvider is used in both server and client?
Hence wouldn't it be possible that this fix "leaked" into the server-side code and is causing the ThreadLocal / ClassLoader leak?

@lprimak

lprimak commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Here are some stack traces, maybe it will shed some ideas?:

Breakpoint reached at org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider$InjectionManagerInjectedCdiTarget.setInjectionManager(CdiComponentProvider.java:743)
Breakpoint reached
	at org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider$InjectionManagerInjectedCdiTarget.setInjectionManager(CdiComponentProvider.java:743)
	at org.glassfish.jersey.ext.cdi1x.internal.GenericInjectionManagerStore.registerInjectionManager(GenericInjectionManagerStore.java:61)
	at org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider.addInjectionManager(CdiComponentProvider.java:588)
	at org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider.initialize(CdiComponentProvider.java:174)
	at org.glassfish.jersey.ext.cdi1x.internal.CdiServerComponentProvider.initialize(CdiServerComponentProvider.java:39)
	at org.glassfish.jersey.server.ComponentProviderConfigurator.lambda$init$0(ComponentProviderConfigurator.java:55)
	at org.glassfish.jersey.server.ComponentProviderConfigurator$$Lambda/0x000007c001a60000.accept(Unknown Source:-1)
	at java.util.stream.ReferencePipeline$15$1.accept(ReferencePipeline.java:576)
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:214)
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1724)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:570)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:265)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:723)
	at org.glassfish.jersey.server.ComponentProviderConfigurator.lambda$init$1(ComponentProviderConfigurator.java:56)
	at org.glassfish.jersey.server.ComponentProviderConfigurator$$Lambda/0x000007c001968498.get(Unknown Source:-1)
	at org.glassfish.jersey.internal.util.collection.Values$LazyValueImpl.get(Values.java:321)
	at org.glassfish.jersey.server.ApplicationConfigurator.createApplication(ApplicationConfigurator.java:100)
	at org.glassfish.jersey.server.ApplicationConfigurator.init(ApplicationConfigurator.java:73)
	at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$0(ApplicationHandler.java:313)
	at org.glassfish.jersey.server.ApplicationHandler$$Lambda/0x000007c001955840.accept(Unknown Source:-1)
	at java.util.Arrays$ArrayList.forEach(Arrays.java:4264)
	at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:313)
	at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:276)
	at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:339)
	at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:151)
	at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:336)
	at jakarta.servlet.GenericServlet.init(GenericServlet.java:178)
	at jakarta.servlet.http.HttpServlet.init(HttpServlet.java:114)
	at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1447)
	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1261)
	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5512)
	at org.apache.catalina.core.StandardContext.start(StandardContext.java:5765)
	at com.sun.enterprise.web.WebModule.start(WebModule.java:514)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:971)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:954)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:694)
	at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1813)
	at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1566)
	at com.sun.enterprise.web.WebApplication.start(WebApplication.java:107)
	at org.glassfish.internal.data.EngineRef.start(EngineRef.java:123)
	at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:292)
	at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:361)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.initialize(ApplicationLifecycle.java:625)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:656)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.enable(ApplicationLifecycle.java:2542)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.enable(ApplicationLifecycle.java:160)
	at com.sun.enterprise.v3.server.ApplicationConfigListener.enableApplication(ApplicationConfigListener.java:267)
	at com.sun.enterprise.v3.server.ApplicationConfigListener.handleAppEnableChange(ApplicationConfigListener.java:202)
	at com.sun.enterprise.v3.server.ApplicationConfigListener.transactionCommited(ApplicationConfigListener.java:176)
	at org.jvnet.hk2.config.Transactions$TransactionListenerJob.process(Transactions.java:367)
	at org.jvnet.hk2.config.Transactions$TransactionListenerJob.process(Transactions.java:358)
	at org.jvnet.hk2.config.Transactions$ListenerNotifier$1.call(Transactions.java:214)
	at java.util.concurrent.FutureTask.run(FutureTask.java:330)
	at org.jvnet.hk2.config.Transactions$Notifier$1$1.run(Transactions.java:168)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:545)
	at java.util.concurrent.FutureTask.run(FutureTask.java:330)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
	at java.lang.Thread.runWith(Thread.java:1529)
	at java.lang.Thread.run(Thread.java:1516)
java.lang.ThreadLocal@3a92d7a8
Breakpoint reached at org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider.done(CdiComponentProvider.java:274)
Breakpoint reached
	at org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider.done(CdiComponentProvider.java:274)
	at org.glassfish.jersey.ext.cdi1x.internal.CdiServerComponentProvider.done(CdiServerComponentProvider.java:56)
	at org.glassfish.jersey.server.ComponentProviderConfigurator$$Lambda/0x000007c001a71028.accept(Unknown Source:-1)
	at java.util.ArrayList.forEach(ArrayList.java:1612)
	at org.glassfish.jersey.server.ComponentProviderConfigurator.postInit(ComponentProviderConfigurator.java:63)
	at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$2(ApplicationHandler.java:372)
	at org.glassfish.jersey.server.ApplicationHandler$$Lambda/0x000007c001a70bd0.accept(Unknown Source:-1)
	at java.util.Arrays$ArrayList.forEach(Arrays.java:4264)
	at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:372)
	at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$1(ApplicationHandler.java:316)
	at org.glassfish.jersey.server.ApplicationHandler$$Lambda/0x000007c001969ba0.call(Unknown Source:-1)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
	at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:232)
	at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:315)
	at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:276)
	at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:339)
	at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:151)
	at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:336)
	at jakarta.servlet.GenericServlet.init(GenericServlet.java:178)
	at jakarta.servlet.http.HttpServlet.init(HttpServlet.java:114)
	at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1447)
	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1261)
	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5512)
	at org.apache.catalina.core.StandardContext.start(StandardContext.java:5765)
	at com.sun.enterprise.web.WebModule.start(WebModule.java:514)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:971)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:954)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:694)
	at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1813)
	at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1566)
	at com.sun.enterprise.web.WebApplication.start(WebApplication.java:107)
	at org.glassfish.internal.data.EngineRef.start(EngineRef.java:123)
	at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:292)
	at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:361)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.initialize(ApplicationLifecycle.java:625)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:656)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.enable(ApplicationLifecycle.java:2542)
	at com.sun.enterprise.v3.server.ApplicationLifecycle.enable(ApplicationLifecycle.java:160)
	at com.sun.enterprise.v3.server.ApplicationConfigListener.enableApplication(ApplicationConfigListener.java:267)
	at com.sun.enterprise.v3.server.ApplicationConfigListener.handleAppEnableChange(ApplicationConfigListener.java:202)
	at com.sun.enterprise.v3.server.ApplicationConfigListener.transactionCommited(ApplicationConfigListener.java:176)
	at org.jvnet.hk2.config.Transactions$TransactionListenerJob.process(Transactions.java:367)
	at org.jvnet.hk2.config.Transactions$TransactionListenerJob.process(Transactions.java:358)
	at org.jvnet.hk2.config.Transactions$ListenerNotifier$1.call(Transactions.java:214)
	at java.util.concurrent.FutureTask.run(FutureTask.java:330)
	at org.jvnet.hk2.config.Transactions$Notifier$1$1.run(Transactions.java:168)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:545)
	at java.util.concurrent.FutureTask.run(FutureTask.java:330)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
	at java.lang.Thread.runWith(Thread.java:1529)
	at java.lang.Thread.run(Thread.java:1516)
TL: java.lang.ThreadLocal@3a92d7a8

@OndroMih

OndroMih commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Can you find out whether the done method is called later? It should remove the thread local.

@breakponchito

Copy link
Copy Markdown

@OndroMih I created the porting PR for the version 3.x here: #6096 right now it is failing because of some licence check validation for JDK 21. Do you know what is causing this issue? and how to solve it? It seems that I need help from someone with more admin right to reatempt the pipeline

@lprimak

lprimak commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Ondro,

done() is getting called, as seen in stack trace above. However, it's not clear that:

  • It's getting called in correct order
  • it's getting called after every ThreadLocal.set() call, in the correct order
  • Since there is a new if() statement to retrieve the extension, it's not clear that is working correctly.

It looks like non-static effectiveInjectionManager ThreadLocal is inside the CdiComponentProvider class
However, all uses of that field are in the non-static inner class InjectionManagerInjectedCdiTarget,
that may cause a different, or non at all, ThreadLocal(s) to be cleaned than is initialized.

I do not have enough context for this fix to tell whats "good" and "bad" behavior here,
but I do know that something is not right and causing the ThreadLocal leak.

@lprimak

lprimak commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

So here is what I am observing:

  • TL gets set
  • done() gets called and TL gets cleared
  • TL gets set (second set of traces)
  • TL gets set again
  • TL never gets cleared

In this stack trace, ThreadLocal gets set, and then done() does get called and the TL gets removed successfuly:

at org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider$InjectionManagerInjectedCdiTarget.setInjectionManager(CdiComponentProvider.java:743)
at org.glassfish.jersey.ext.cdi1x.internal.GenericInjectionManagerStore.registerInjectionManager(GenericInjectionManagerStore.java:61)
at org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider.addInjectionManager(CdiComponentProvider.java:588)
at org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider.initialize(CdiComponentProvider.java:174)
at org.glassfish.jersey.ext.cdi1x.internal.CdiServerComponentProvider.initialize(CdiServerComponentProvider.java:39)
at org.glassfish.jersey.server.ComponentProviderConfigurator.lambda$init$0(ComponentProviderConfigurator.java:55)
at org.glassfish.jersey.server.ComponentProviderConfigurator$$Lambda/0x0000600001aada00.accept(Unknown Source:-1)
at java.util.stream.ReferencePipeline$15$1.accept(ReferencePipeline.java:576)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:214)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1724)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:570)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:265)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:723)
at org.glassfish.jersey.server.ComponentProviderConfigurator.lambda$init$1(ComponentProviderConfigurator.java:56)
at org.glassfish.jersey.server.ComponentProviderConfigurator$$Lambda/0x00006000019bddc8.get(Unknown Source:-1)
at org.glassfish.jersey.internal.util.collection.Values$LazyValueImpl.get(Values.java:321)
at org.glassfish.jersey.server.ApplicationConfigurator.createApplication(ApplicationConfigurator.java:100)
at org.glassfish.jersey.server.ApplicationConfigurator.init(ApplicationConfigurator.java:73)
at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$0(ApplicationHandler.java:313)
at org.glassfish.jersey.server.ApplicationHandler$$Lambda/0x00006000019a5a80.accept(Unknown Source:-1)
at java.util.Arrays$ArrayList.forEach(Arrays.java:4264)
at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:313)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:276)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:339)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:151)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:336)
at jakarta.servlet.GenericServlet.init(GenericServlet.java:178)
at jakarta.servlet.http.HttpServlet.init(HttpServlet.java:114)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1447)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1261)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5512)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:5765)
at com.sun.enterprise.web.WebModule.start(WebModule.java:514)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:971)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:954)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:694)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1813)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1566)
at com.sun.enterprise.web.WebApplication.start(WebApplication.java:107)
at org.glassfish.internal.data.EngineRef.start(EngineRef.java:123)
at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:292)
at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:361)
at com.sun.enterprise.v3.server.ApplicationLifecycle.initialize(ApplicationLifecycle.java:625)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:656)
at com.sun.enterprise.v3.server.ApplicationLifecycle.enable(ApplicationLifecycle.java:2542)
at com.sun.enterprise.v3.server.ApplicationLifecycle.enable(ApplicationLifecycle.java:160)
at com.sun.enterprise.v3.server.ApplicationConfigListener.enableApplication(ApplicationConfigListener.java:267)
at com.sun.enterprise.v3.server.ApplicationConfigListener.handleAppEnableChange(ApplicationConfigListener.java:202)
at com.sun.enterprise.v3.server.ApplicationConfigListener.transactionCommited(ApplicationConfigListener.java:176)
at org.jvnet.hk2.config.Transactions$TransactionListenerJob.process(Transactions.java:367)
at org.jvnet.hk2.config.Transactions$TransactionListenerJob.process(Transactions.java:358)
at org.jvnet.hk2.config.Transactions$ListenerNotifier$1.call(Transactions.java:214)
at java.util.concurrent.FutureTask.run(FutureTask.java:330)
at org.jvnet.hk2.config.Transactions$Notifier$1$1.run(Transactions.java:168)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:545)
at java.util.concurrent.FutureTask.run(FutureTask.java:330)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
at java.lang.Thread.runWith(Thread.java:1529)
at java.lang.Thread.run(Thread.java:1516)

Here is the done() stack trace:

at org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider.done(CdiComponentProvider.java:272)
at org.glassfish.jersey.ext.cdi1x.internal.CdiServerComponentProvider.done(CdiServerComponentProvider.java:56)
at org.glassfish.jersey.server.ComponentProviderConfigurator$$Lambda/0x0000600001aba328.accept(Unknown Source:-1)
at java.util.ArrayList.forEach(ArrayList.java:1612)
at org.glassfish.jersey.server.ComponentProviderConfigurator.postInit(ComponentProviderConfigurator.java:63)
at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$2(ApplicationHandler.java:372)
at org.glassfish.jersey.server.ApplicationHandler$$Lambda/0x0000600001ab9ed0.accept(Unknown Source:-1)
at java.util.Arrays$ArrayList.forEach(Arrays.java:4264)
at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:372)
at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$1(ApplicationHandler.java:316)
at org.glassfish.jersey.server.ApplicationHandler$$Lambda/0x00006000019bf4d0.call(Unknown Source:-1)
at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:232)
at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:315)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:276)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:339)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:151)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:336)
at jakarta.servlet.GenericServlet.init(GenericServlet.java:178)
at jakarta.servlet.http.HttpServlet.init(HttpServlet.java:114)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1447)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1261)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5512)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:5765)
at com.sun.enterprise.web.WebModule.start(WebModule.java:514)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:971)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:954)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:694)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1813)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1566)
at com.sun.enterprise.web.WebApplication.start(WebApplication.java:107)
at org.glassfish.internal.data.EngineRef.start(EngineRef.java:123)
at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:292)
at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:361)
at com.sun.enterprise.v3.server.ApplicationLifecycle.initialize(ApplicationLifecycle.java:625)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:656)
at com.sun.enterprise.v3.server.ApplicationLifecycle.enable(ApplicationLifecycle.java:2542)
at com.sun.enterprise.v3.server.ApplicationLifecycle.enable(ApplicationLifecycle.java:160)
at com.sun.enterprise.v3.server.ApplicationConfigListener.enableApplication(ApplicationConfigListener.java:267)
at com.sun.enterprise.v3.server.ApplicationConfigListener.handleAppEnableChange(ApplicationConfigListener.java:202)
at com.sun.enterprise.v3.server.ApplicationConfigListener.transactionCommited(ApplicationConfigListener.java:176)
at org.jvnet.hk2.config.Transactions$TransactionListenerJob.process(Transactions.java:367)
at org.jvnet.hk2.config.Transactions$TransactionListenerJob.process(Transactions.java:358)
at org.jvnet.hk2.config.Transactions$ListenerNotifier$1.call(Transactions.java:214)
at java.util.concurrent.FutureTask.run(FutureTask.java:330)
at org.jvnet.hk2.config.Transactions$Notifier$1$1.run(Transactions.java:168)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:545)
at java.util.concurrent.FutureTask.run(FutureTask.java:330)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
at java.lang.Thread.runWith(Thread.java:1529)
at java.lang.Thread.run(Thread.java:1516)

In the below stack trace, the ThreadLocal gets set, but never removed, since done() never gets called afterwards:

at org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider$InjectionManagerInjectedCdiTarget.setInjectionManager(CdiComponentProvider.java:743)
at org.glassfish.jersey.ext.cdi1x.internal.AbstractCdiBeanSupplier$2.getInstance(AbstractCdiBeanSupplier.java:102)
at org.glassfish.jersey.ext.cdi1x.internal.AbstractCdiBeanSupplier._provide(AbstractCdiBeanSupplier.java:138)
at org.glassfish.jersey.ext.cdi1x.internal.GenericCdiBeanSupplier.get(GenericCdiBeanSupplier.java:42)
at org.glassfish.jersey.inject.hk2.InstanceSupplierFactoryBridge.provide(InstanceSupplierFactoryBridge.java:53)
at org.jvnet.hk2.internal.FactoryCreator.create(FactoryCreator.java:129)
at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:479)
at org.jvnet.hk2.internal.PerLookupContext.findOrCreate(PerLookupContext.java:46)
at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2111)
at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:98)
at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:68)
at org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.lambda$getAllServiceHolders$0(AbstractHk2InjectionManager.java:137)
at org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager$$Lambda/0x000060000199d8d8.apply(Unknown Source:-1)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:214)
at java.util.LinkedList$LLSpliterator.forEachRemaining(LinkedList.java:1250)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:570)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:265)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:723)
at org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.getAllServiceHolders(AbstractHk2InjectionManager.java:141)
at org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager.getAllServiceHolders(ImmediateHk2InjectionManager.java:30)
at org.glassfish.jersey.internal.inject.Providers.getServiceHolders(Providers.java:323)
at org.glassfish.jersey.internal.inject.Providers.getCustomProviders(Providers.java:167)
at org.glassfish.jersey.message.internal.MessageBodyFactory.initialize(MessageBodyFactory.java:221)
at org.glassfish.jersey.message.internal.MessageBodyFactory$MessageBodyWorkersConfigurator.postInit(MessageBodyFactory.java:116)
at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$2(ApplicationHandler.java:372)
at org.glassfish.jersey.server.ApplicationHandler$$Lambda/0x0000600001ab9ed0.accept(Unknown Source:-1)
at java.util.Arrays$ArrayList.forEach(Arrays.java:4264)
at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:372)
at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$1(ApplicationHandler.java:316)
at org.glassfish.jersey.server.ApplicationHandler$$Lambda/0x00006000019bf4d0.call(Unknown Source:-1)
at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:232)
at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:315)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:276)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:339)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:151)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:336)
at jakarta.servlet.GenericServlet.init(GenericServlet.java:178)
at jakarta.servlet.http.HttpServlet.init(HttpServlet.java:114)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1447)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1261)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5512)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:5765)
at com.sun.enterprise.web.WebModule.start(WebModule.java:514)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:971)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:954)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:694)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1813)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1566)
at com.sun.enterprise.web.WebApplication.start(WebApplication.java:107)
at org.glassfish.internal.data.EngineRef.start(EngineRef.java:123)
at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:292)
at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:361)
at com.sun.enterprise.v3.server.ApplicationLifecycle.initialize(ApplicationLifecycle.java:625)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:656)
at com.sun.enterprise.v3.server.ApplicationLifecycle.enable(ApplicationLifecycle.java:2542)
at com.sun.enterprise.v3.server.ApplicationLifecycle.enable(ApplicationLifecycle.java:160)
at com.sun.enterprise.v3.server.ApplicationConfigListener.enableApplication(ApplicationConfigListener.java:267)
at com.sun.enterprise.v3.server.ApplicationConfigListener.handleAppEnableChange(ApplicationConfigListener.java:202)
at com.sun.enterprise.v3.server.ApplicationConfigListener.transactionCommited(ApplicationConfigListener.java:176)
at org.jvnet.hk2.config.Transactions$TransactionListenerJob.process(Transactions.java:367)
at org.jvnet.hk2.config.Transactions$TransactionListenerJob.process(Transactions.java:358)
at org.jvnet.hk2.config.Transactions$ListenerNotifier$1.call(Transactions.java:214)
at java.util.concurrent.FutureTask.run(FutureTask.java:330)
at org.jvnet.hk2.config.Transactions$Notifier$1$1.run(Transactions.java:168)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:545)
at java.util.concurrent.FutureTask.run(FutureTask.java:330)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
at java.lang.Thread.runWith(Thread.java:1529)
at java.lang.Thread.run(Thread.java:1516)

@OndroMih

OndroMih commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

@lprimak , are you sure you're running Jersey with this change? In your stacktrace, there's org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:315) but there's no executable code on line 315: https://github.com/eclipse-ee4j/jersey/blob/4.x/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java#L315

@lprimak

lprimak commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

I am testing on Payara, they have their own patched version of Jersey, so the line numbers don't always match.
See https://github.com/payara/patched-src-jersey/tree/jersey-4.0.2.payara-maintenance

@arjantijms

Copy link
Copy Markdown
Contributor

I am testing on Payara, they have their own patched version of Jersey, so the line numbers don't always match.

Maybe just for total sanity, but can you try with the non-patched (regular) version?

@OndroMih

OndroMih commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

I tried running on Payara Micro with stock Jersey jars and can't reproduce the issue. The issue also doesn't happen in Embedded GlassFish 8.0.3. I can only see the issue in stock Payara Micro, which contains patched Jersey jars.

See more details here: #6099 (comment)

@lprimak

lprimak commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

@arjantijms I ran un-patched 4.0.2 and the same issue exists. The errors printed are just the symptom, not the cause. They do not always appear.

@breakponchito I would hold off working on the ports. This PR breaks all app servers, including GlassFish and Payara.

@OndroMih

OndroMih commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

Are you sure about that? I debugged Embedded GlassFish 8.0.3 and it doesn't execute the initialize method and setInjectionManager after the done method is called which removes the thread local.

@lprimak

lprimak commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Yes, 100%
You can also see this in the stack traces above. I did not invent those :)

Just to make it clear, this is the offending stack trace resulting in set():

at org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider$InjectionManagerInjectedCdiTarget.setInjectionManager(CdiComponentProvider.java:743)
at org.glassfish.jersey.ext.cdi1x.internal.AbstractCdiBeanSupplier$2.getInstance(AbstractCdiBeanSupplier.java:102)
at org.glassfish.jersey.ext.cdi1x.internal.AbstractCdiBeanSupplier._provide(AbstractCdiBeanSupplier.java:138)
at org.glassfish.jersey.ext.cdi1x.internal.GenericCdiBeanSupplier.get(GenericCdiBeanSupplier.java:42)
at org.glassfish.jersey.inject.hk2.InstanceSupplierFactoryBridge.provide(InstanceSupplierFactoryBridge.java:53)
at org.jvnet.hk2.internal.FactoryCreator.create(FactoryCreator.java:129)
at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:479)
at org.jvnet.hk2.internal.PerLookupContext.findOrCreate(PerLookupContext.java:46)
at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2111)
at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:98)
at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:68)
at org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.lambda$getAllServiceHolders$0(AbstractHk2InjectionManager.java:137)
at org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager$$Lambda/0x000060000199d8d8.apply(Unknown Source:-1)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:214)
at java.util.LinkedList$LLSpliterator.forEachRemaining(LinkedList.java:1250)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:570)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:265)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:723)
at org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.getAllServiceHolders(AbstractHk2InjectionManager.java:141)
at org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager.getAllServiceHolders(ImmediateHk2InjectionManager.java:30)
at org.glassfish.jersey.internal.inject.Providers.getServiceHolders(Providers.java:323)
at org.glassfish.jersey.internal.inject.Providers.getCustomProviders(Providers.java:167)
at org.glassfish.jersey.message.internal.MessageBodyFactory.initialize(MessageBodyFactory.java:221)
at org.glassfish.jersey.message.internal.MessageBodyFactory$MessageBodyWorkersConfigurator.postInit(MessageBodyFactory.java:116)
at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$2(ApplicationHandler.java:372)
at org.glassfish.jersey.server.ApplicationHandler$$Lambda/0x0000600001ab9ed0.accept(Unknown Source:-1)
at java.util.Arrays$ArrayList.forEach(Arrays.java:4264)
at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:372)
at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$1(ApplicationHandler.java:316)
at org.glassfish.jersey.server.ApplicationHandler$$Lambda/0x00006000019bf4d0.call(Unknown Source:-1)
at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:232)
at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:315)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:276)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:339)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:151)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:336)
at jakarta.servlet.GenericServlet.init(GenericServlet.java:178)
at jakarta.servlet.http.HttpServlet.init(HttpServlet.java:114)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1447)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1261)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5512)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:5765)
at com.sun.enterprise.web.WebModule.start(WebModule.java:514)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:971)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:954)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:694)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1813)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1566)
at com.sun.enterprise.web.WebApplication.start(WebApplication.java:107)
at org.glassfish.internal.data.EngineRef.start(EngineRef.java:123)
at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:292)
at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:361)
at com.sun.enterprise.v3.server.ApplicationLifecycle.initialize(ApplicationLifecycle.java:625)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:656)
at com.sun.enterprise.v3.server.ApplicationLifecycle.enable(ApplicationLifecycle.java:2542)
at com.sun.enterprise.v3.server.ApplicationLifecycle.enable(ApplicationLifecycle.java:160)
at com.sun.enterprise.v3.server.ApplicationConfigListener.enableApplication(ApplicationConfigListener.java:267)
at com.sun.enterprise.v3.server.ApplicationConfigListener.handleAppEnableChange(ApplicationConfigListener.java:202)
at com.sun.enterprise.v3.server.ApplicationConfigListener.transactionCommited(ApplicationConfigListener.java:176)
at org.jvnet.hk2.config.Transactions$TransactionListenerJob.process(Transactions.java:367)
at org.jvnet.hk2.config.Transactions$TransactionListenerJob.process(Transactions.java:358)
at org.jvnet.hk2.config.Transactions$ListenerNotifier$1.call(Transactions.java:214)
at java.util.concurrent.FutureTask.run(FutureTask.java:330)
at org.jvnet.hk2.config.Transactions$Notifier$1$1.run(Transactions.java:168)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:545)
at java.util.concurrent.FutureTask.run(FutureTask.java:330)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
at java.lang.Thread.runWith(Thread.java:1529)
at java.lang.Thread.run(Thread.java:1516)

@dmatej
dmatej deleted the ondromih-2026-01-ClassAnalyzer-race-condition-pr branch July 8, 2026 20:18
@dmatej dmatej added this to the 4.0.1 milestone Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants