Documentation
Reference Documentation
Weld 7 Latest
Reference implementation of CDI 5.0
Weld Reference CDI SpecificationWeld 6
Reference implementation of CDI 4.1
Weld Reference CDI SpecificationWeld 5
Reference implementation of CDI 4.0
Weld Reference CDI SpecificationWeld 4
Reference implementation of CDI 3.0
Weld Reference CDI SpecificationWeld 3
Reference implementation of CDI 2.0
Weld Reference CDI SpecificationFrequently Asked Questions
Weld assumes requests are single threaded, and uses thread locals to isolate requests. This means that if user created threads are used then built in implementation of the session scope, the request scope and the conversation scope, will become dissociated, and you will find they are no longer active in the new thread, nor able to access their contextual data.
The dependent context and the application context will work as usual in any user created thread.
If you need to activate a fresh request context on a new thread, you can use the standard CDI RequestContextController API or the @ActivateRequestContext interceptor binding. However, if you need full context propagation — transferring existing bean instances from one thread to another — you will need to use Weld-specific interfaces such as WeldAlterableContext and WeldManager. See the Propagating built-in contexts section of the Weld reference guide for details and examples.
When a Weld-enabled application is deployed on an application server or a web server, proxy classes for beans implementing interfaces or extending classes contained in common libraries are loaded in the class loader (CL) for that library, not the thread context class loader (TCCL). This means that these proxy classes will not be removed from the server when the application is undeployed.
The reason for this approach is to support the use of package scoped classes and members of classes which need to be proxied as beans. Thus the TCCL is not used for the proxy classes generated by Weld.
One way to prevent this problem is to simply deploy those libraries with your application. In this scenario, those classes are loaded in a CL associated with the application and will thus be removed when the application is undeployed.
Weld will not create beans if it can't load the class, or some class dependency. If that happens, you'll see a note in the server log.
WELD-000119: Not generating any bean definitions from org.jboss.weld.tests.beanDeployment.noclassdeffound.Bar because of underlying class loading error
You can view more details by increasing the log level of the application server to DEBUG.
This primarily affects @Dependent scoped beans. Each @Dependent bean instance obtained via Instance.get() remains managed (is not released) until the Instance object itself is destroyed. Since the Instance is tied to the lifecycle of the bean that holds it, this can easily cause a memory leak — especially when Instance.get() is called in a loop from a long-lived bean such as @ApplicationScoped.
Normal-scoped beans (e.g. @RequestScoped, @ApplicationScoped) are not affected because they are stored in their respective context and cleaned up when the context ends.
For example:
@Inject
private Instance<A> instance;
public void foo() {
// obtain multiple instances of A
for (;;) {
A a = instance.get();
// use the instance ...
instance.destroy(a);
}
}
The application should explicitly destroy @Dependent instances when no longer needed by calling Instance.destroy(). Alternatively, you can use Instance.Handle which implements AutoCloseable:
@Inject
private Instance<A> instance;
public void foo() {
try (Instance.Handle<A> handle = instance.getHandle()) {
A a = handle.get();
// use the instance
}
}
When things do not work as expected, more information might be helpful in solving the problem. For this reason, you might want to enable the debug (fine) log level for Weld. Each container has its own way to do this:
WildFly
(more info: Application Logging - WildFly)
global configuration - add the following content to the logging subsystem in $JBOSS_HOME/standalone/configuration/standalone-full.xml
<logger category="org.jboss.weld">
<level name="DEBUG"/>
</logger>
per-deployment configuration - add the following line to the logging configuration file (e.g. META-INF/logging.properties) of the application
org.jboss.weld.level=DEBUG
Tip: If you want to see the debug messages also in the console, make sure the console handler's level is set to at least DEBUG.
GlassFish
(more info: Administering the Logging Service - GlassFish)
using asadmin:
asadmin set-log-levels org.jboss.weld=FINE
or add the following line to _domain-dir_/config/logging.properties
org.jboss.weld.level=FINE
Payara
(more info: Administering the Logging Service - Payara)
using asadmin:
asadmin set-log-levels org.jboss.weld=FINE
or add the following line to _domain-dir_/config/logging.properties
org.jboss.weld.level=FINE
Tomcat
(more info: Logging in Tomcat)
global configuration - add the following line to $CATALINA_HOME/conf/logging.properties
org.jboss.weld.level=FINE
per-deployment configuration - add the following line to WEB-INF/classes/logging.properties
org.jboss.weld.level=FINE
Jetty
(more info: Logging - Jetty)
Jetty uses SLF4J. When using the default Jetty SLF4J binding, set the log level in jetty-logging.properties:
org.jboss.weld.LEVEL=DEBUG
If you use a different SLF4J binding (e.g. Logback, Log4j2), configure it according to that framework's documentation.
When running on Tomcat with asynchronous Servlets you may observe the following warnings:
WARN: WELD-000225: Bean store leak was detected during org.jboss.weld.context.http.HttpSessionContextImpl association: org.apache.catalina.connector.Request@5d22c824
WARN: WELD-000335: Conversation context is already active, most likely it was not cleaned up properly during previous request processing: org.apache.catalina.connector.Request@5d22c824
WARN: WELD-000715: HttpContextLifecycle guard not set. The Servlet container is not fully compliant.
A hook exists in the Servlet specification for integrating frameworks such as Weld into a Servlet container.
This hooks is called ServletRequestListener. The problem here is that Tomcat implements these hooks in a different
way than all the other implementations (Undertow, JBoss Web, Jetty and Grizzly).
Tomcat's implementation does not allow for an integrating framework that uses ThreadLocals (like Weld does) to be used
correctly in asynchronous Servlet requests. As a result, these warnings are observed as Weld is not able to clean up contexts and
bean instances properly at the end of a request. See the Tomcat bug report
for more details.
Weld versions do not match CDI versioning. An overview is provided in the following table:
| Weld version | CDI version | Java version | EE version | Description |
|---|---|---|---|---|
| 7.0 | 5.0 | 17+ | Jakarta EE 12 | In development |
| 6.0 | 4.1 | 17+ | Jakarta EE 11 | Latest stable version of Weld |
| 5.1 | 4.0 | 11+ | Jakarta EE 10 | In maintenance mode |
| 4.0 | 3.0 | 8+ | Jakarta EE 9 | Namespace change from javax to jakarta |
| 3.1 | 2.0 | 8+ | Java EE 8 | Not actively developed anymore |
| 2.4 | 1.2 | 7+ | Java EE 7 | Not actively developed anymore |
| 1.1 | 1.0 | 6+ | Java EE 6 | Not actively developed anymore |
Weld uses JBoss Logging which provides support for the internationalization and localization of log messages and exception messages. However, JBoss Logging itself does not write any log messages. Instead, it only constructs a log message and delegates to one of the supported logging frameworks. If no framework is explicitly configured, JBoss Logging auto-discovers one from the classpath in the following order:
You can force a specific framework using the system property org.jboss.logging.provider with values jboss, log4j2, slf4j, or jdk.
SLF4J / Logback
SLF4J is a logging facade and Logback is its native implementation. JBoss Logging auto-discovers SLF4J when Logback is on the classpath. Add ch.qos.logback:logback-classic to the classpath and configure logback.xml:
<configuration>
<logger name="org.jboss.weld" level="DEBUG"/>
</configuration>
Log4j2
Add org.apache.logging.log4j:log4j-core to the classpath and configure log4j2.xml:
<Loggers>
<Logger name="org.jboss.weld" level="DEBUG"/>
</Loggers>
JDK logging
No extra dependencies needed. Set the level in logging.properties:
org.jboss.weld.level=FINE
handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=FINE
Quick setup for testing
If you just want to see debug messages as quickly as possible, add org.slf4j:slf4j-simple to the classpath and run with:
mvn clean test -Dtest=MyWeldSETest -Dorg.jboss.logging.provider=slf4j -Dorg.slf4j.simpleLogger.log.org.jboss.weld=debug
Note that slf4j-simple requires the explicit -Dorg.jboss.logging.provider=slf4j system property because JBoss Logging only auto-discovers SLF4J when Logback is present.
Current versions of Weld support Jetty 12 and newer. When starting Jetty as an embedded webapp server from within another Java program, no further configuration is needed.
For a standalone Jetty instance, you need to enable the Jetty CDI module. The module name depends on which Jakarta EE version you target: ee10-cdi for Jakarta EE 10 (Jetty 12.0.x) or ee11-cdi for Jakarta EE 11 (Jetty 12.1.x):
cd $JETTY_BASE
java -jar $JETTY_HOME/start.jar --add-modules=ee11-cdi
See the Weld reference guide and the Jetty examples for more details.
Each version of WildFly is shipped with a given version of Weld. If you want to upgrade Weld in your WildFly installation, you can use the upgrade script from the Weld source repository.
Clone the repository and checkout the tag or branch for the Weld version you want. Then set the JBOSS_HOME environment variable and run:
export JBOSS_HOME=/path/to/wildfly
mvn package -Pupdate-jboss-as -f jboss-as/pom.xml -Dweld.update.version=6.0.4.Final
Replace 6.0.4.Final with the Weld version you want to use. The script will replace the Weld modules in your WildFly installation.
Note that upgrading Weld to a version that targets a different CDI specification than the one shipped with your WildFly may require additional changes.
Both these contexts behave very similarly. A single bean instance is created and shared across the application. However, there are some important differences.
Client Proxy
First of all, @ApplicationScoped is a normal scope whereas @Singleton is a pseudo-scope (using the CDI terminology).
What does it mean?
In the first place, for normal scopes a client proxy is always injected.
This is a container construct that delegates all method calls to the current bean instance.
While this may seem as an unnecessary overhead, it allows the container to do the following:
Serialization
The client proxies are serializable even when the bean itself may not be.
Therefore, you can @Inject a normal-scoped bean into a bean with a passivating scope (such as @SessionScoped).
See Weld Reference Guide for more information.
Lazy Creation
The container initializes the bean instances of normal scoped beans lazily.
In other words, when injecting an @ApplicationScoped bean a new instance is not created until actually used.
Instead, a shared client proxy is injected.
See Weld Tip 3 - Boost performance of Weld apps for more information.
Circular Dependencies
Client proxies make it possible to support circularities in the bean dependency graph.
Manual Bean Destruction
There are also some use cases where it's desirable to destroy/recreate a bean instance via Instance.destroy() or AlterableContext.destroy().
With client proxy in place, all injection points operate on proxy objects that can lookup the contextual instance on demand therefore making it simple and safe to replace the contextual instance for a new one.
On the other hand injecting a direct reference and attempting the same would lead to stale bean instances or working with outdated states of those instances.
This only affects applications that use a completely empty beans.xml file (a file with no XML content at all). Applications with a beans.xml that contains XML content are not affected — the bean-discovery-mode attribute defaults to annotated per the schema regardless.
Starting with CDI 4.0 (Jakarta EE 10), the default bean discovery mode changed. Previously, an empty beans.xml was treated as discovery mode all, meaning all classes in the archive were discovered as beans. Since CDI 4.0, an empty beans.xml is treated as discovery mode annotated — only classes with a bean defining annotation (such as @ApplicationScoped, @RequestScoped, @Dependent, etc.) are discovered.
If your application relied on the old behavior, you have two options:
Option 1: Add bean defining annotations (recommended)
Add a scope annotation to each bean class that should be discovered:
@ApplicationScoped
public class MyService {
// ...
}
This is the recommended approach and ensures your application works correctly with all CDI implementations.
Option 2: Explicitly set discovery mode to all
Update your beans.xml to explicitly request all discovery:
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd"
version="4.0" bean-discovery-mode="all">
</beans>
Weld compatibility option (temporary)
Weld also provides a compatibility option to temporarily restore the old behavior where empty beans.xml means all discovery. This is intended to ease migration and should not be relied upon long-term.
For Weld SE:
try (WeldContainer container = new Weld()
.property(Weld.LEGACY_EMPTY_BEANS_XML_TREATMENT, true)
.initialize()) {
// ...
}
For Weld Servlet, set the ServletContext parameter org.jboss.weld.environment.servlet.emptyBeansXmlModeAll to true.
For WildFly, consult the WildFly documentation for the corresponding configuration option.
See the Weld reference guide for more details.
