Skip to content

Remove thread-context-classloader hack in Weld BDA; rely on per-BDA ResourceLoader SPI#26090

Open
renatsaf wants to merge 1 commit into
eclipse-ee4j:mainfrom
renatsaf:code-cleanup-issue-25593-weld-classloader
Open

Remove thread-context-classloader hack in Weld BDA; rely on per-BDA ResourceLoader SPI#26090
renatsaf wants to merge 1 commit into
eclipse-ee4j:mainfrom
renatsaf:code-cleanup-issue-25593-weld-classloader

Conversation

@renatsaf

Copy link
Copy Markdown
Contributor

Summary

Fixes #25593.

BeanDeploymentArchiveImpl.getBeanClasses() set the thread context classloader (TCL) to the BDA's module classloader as a side effect — a long-standing workaround for WELD-781, introduced back in #18152, from before Weld offered an SPI to control the classloader per bean deployment archive.

That side effect is fragile: a getter mutates global thread state, so it leaks into any caller (e.g. toString()), and when a BDA uses a custom classloader the TCL stays set for the rest of the Weld deployment because GlassFish only restores it at the end of WeldDeployer.enable().

The SPI has long since landed and GlassFish already uses it:

  • per-BDA ResourceLoader — registered in WeldDeployer.enable() with getModuleClassLoaderForBDA(), so Weld loads each archive's classes/resources with the correct classloader;
  • ProxyServices — resolves the bean's own classloader for proxy generation.

The TCL manipulation is therefore redundant.

Changes

  • BeanDeploymentArchiveImpl.getBeanClasses() is now a pure getter (no TCL side effect).
  • Removed the dependent machinery: the deploymentComplete flag and its is/set accessors, the originalClassLoader save/restore and deploymentComplete() call in WeldDeployer.enable(), and the now-orphaned AS-CDI-00001 "Setting Context Class Loader" log message.

Notes / risk

Behavioral change: during Weld bootstrap the TCL is no longer mutated to each BDA's module classloader; it stays as the deployment-time classloader. ProxyServicesImpl still falls back to the TCL only for non-application beans (e.g. UserTransaction proxies), which now resolve against the application classloader — a reasonable choice. As the issue notes there is no functional reproducer today, so correctness rests on the CDI/Weld TCKs (multi-module EARs, RARs, WEB-INF/lib bean archives, built-in-bean proxies).

🤖 Generated with Claude Code

…esourceLoader SPI

BeanDeploymentArchiveImpl.getBeanClasses() set the thread context
classloader to the BDA's module classloader as a side effect, a
workaround for WELD-781 from before Weld offered an SPI to control the
classloader per bean deployment archive. The side effect leaked into any
caller of this getter (e.g. toString()) and, when the BDA classloader is
a custom one, remained set for the rest of the Weld deployment because
GlassFish only reset it at the end of WeldDeployer.enable().

Weld now resolves classes and resources of each archive through the
per-BDA ResourceLoader SPI, which GlassFish already registers in
WeldDeployer.enable() using getModuleClassLoaderForBDA(); proxy
generation goes through ProxyServices. The TCL manipulation is therefore
redundant.

Make getBeanClasses() a pure getter and drop the dependent machinery:
the deploymentComplete flag with its accessors, the originalClassLoader
save/restore and deploymentComplete() call in WeldDeployer.enable(), and
the now-orphaned AS-CDI-00001 "Setting Context Class Loader" log message.

Fixes eclipse-ee4j#25593

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

Instruct Weld to use a specific classloader instead of hacky solution with thread context classloader

1 participant