Weld Reference Guide

Weld is the reference implementation of CDI, and is used by WildFly, GlassFish and WebLogic to provide CDI services for Java Enterprise Edition (Java EE) applications. Weld also goes beyond the environments and APIs defined by the CDI specification by providing support for a number of other environments (such as a servlet container such as Tomcat, or Java SE).

You might also want to check out DeltaSpike project which provides portable extensions to CDI.

If you want to get started quickly using Weld (and, in turn, CDI) with WildFly, GlassFish or Tomcat and experiment with one of the examples, take a look at Getting started with Weld . Otherwise read on for a exhaustive discussion of using Weld in all the environments and application servers it supports and the Weld extensions.

Weld 3.1.7.Final - CDI Reference Implementation

Application servers and environments supported by Weld

Using Weld with WildFly

WildFly comes with pre-configured Weld. There is no configuration needed to use Weld (or CDI for that matter). You may still want to fine-tune Weld with additional configuration settings .

GlassFish

Weld is also built into GlassFish from V3 onwards. Since GlassFish is the Java EE reference implementation, it supports all features of CDI. What better way for GlassFish to support these features than to use Weld, the CDI reference implementation? Just package up your CDI application and deploy.

Servlet containers (such as Tomcat or Jetty)

While CDI does not require support for servlet environments, Weld can be used in a servlet container, such as Tomcat or Jetty.

Note
There is a major limitation to using a servlet container; Weld doesn’t support deploying session beans, injection using @EJB or @PersistenceContext, or using transactional events in servlet containers. For enterprise features such as these, you should really be looking at a Java EE application server.

Weld can be used as a library in an web application that is deployed to a Servlet container. You should add the weld-servlet-core as a dependency to your project:

<dependency>
    <groupId>org.jboss.weld.servlet</groupId>
    <artifactId>weld-servlet-core</artifactId>
    <version>3.1.7.Final</version>
</dependency>

All the necessary dependencies (CDI API, Weld core) will be fetched transitively.

Alternatively, there is a shaded version with all the dependencies in a single jar file which is available as:

<dependency>
    <groupId>org.jboss.weld.servlet</groupId>
    <artifactId>weld-servlet-shaded</artifactId>
    <version>3.1.7.Final</version>
</dependency>

In general, weld-servlet uses ServletContainerInitializer mechanism to hook into the life cycle of Servlet 3.x compatible containers.

In special cases when your Servlet container does not support ServletContainerInitializer or you need more control over the ordering of listeners (e.g. move Weld’s listener) to the beginning of the list so that CDI context are active during invocation of other listeners) you can register Weld’s listener manually in the WEB-INF/web.xml file of the application:

<listener>
   <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>
Note
There is quite a special use-case where one more special component must be involved. If you want the session context to be active during HttpSessionListener.sessionDestroyed() invocation when the session times out or when all the sessions are destroyed because the deployment is being removed then org.jboss.weld.module.web.servlet.WeldTerminalListener must be specified as the last one in your web.xml. This listener activates the session context before other listeners are invoked (note that the listeners are notified in reverse order when a session is being destroyed).

When working with multiple deployments in servlet environment, Weld Servlet allows to define context identifier per application deployed. Each different context identifier will create a new Weld container instance. If not specified, Weld falls back to the default value - STATIC_INSTANCE. While using custom identifiers is neither required nor commonly used, it certainly has some use-cases. For instance managing several deployments with Arquillian Tomcat container. Setting the identifier is as simple as adding one context parameter into web.xml:

<context-param>
   <param-name>WELD_CONTEXT_ID_KEY</param-name>
   <param-value>customValue</param-value>
</context-param>

Tomcat

Tomcat 9, which implements Servlet 4.0 specification, is supported.

Binding BeanManager to JNDI

Binding BeanManager to JNDI does not work out of the box. Tomcat has a read-only JNDI, so Weld can’t automatically bind the BeanManager extension SPI. To bind the BeanManager into JNDI, you should populate META-INF/context.xml in the web root with the following contents:

<Context>
   <Resource name="BeanManager"
      auth="Container"
      type="javax.enterprise.inject.spi.BeanManager"
      factory="org.jboss.weld.resources.ManagerObjectFactory"/>
</Context>

and make it available to your deployment by adding this to the bottom of web.xml:

<resource-env-ref>
   <resource-env-ref-name>BeanManager</resource-env-ref-name>
   <resource-env-ref-type>
      javax.enterprise.inject.spi.BeanManager
   </resource-env-ref-type>
</resource-env-ref>

Tomcat only allows you to bind entries to java:comp/env, so the BeanManager will be available at java:comp/env/BeanManager

Embedded Tomcat

With embedded Tomcat it is necessary to register Weld’s listener programmatically:

public class Main {

    public static void main(String[] args) throws ServletException, LifecycleException {
        Tomcat tomcat = new Tomcat();
        Context ctx = tomcat.addContext("/", new File("src/main/resources").getAbsolutePath());

        Tomcat.addServlet(ctx, "hello", HelloWorldServlet.class.getName());
        ctx.addServletMapping("/*", "hello");

        // ctx.addApplicationListener(Listener.class.getName()); # (1)

        tomcat.start();
        tomcat.getServer().await();
    }

    public static class HelloWorldServlet extends HttpServlet {

        @Inject
        private BeanManager manager;

        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/plain");
            resp.getWriter().append("Hello from " + manager);
        }
    }
}
  1. Weld’s org.jboss.weld.environment.servlet.Listener registered programmatically

Jetty

Jetty 9.4.14 and newer are supported. Context activation/deactivation and dependency injection into Servlets and Filters works out of the box. Injection into Servlet listeners works on Jetty 9.1.1 and newer.

No further configuration is needed when starting Jetty as an embedded webapp server from within another Java program. However, if you’re using a Jetty standalone instance one more configuration step is required, one of the jetty modules listed below needs to be enabled.

Jetty cdi-decorate Module

Since Jetty-9.4.20 and Weld 3.1.2.Final, the Weld/Jetty integration uses the jetty cdi-decorate module. To activate this module in jetty the argument --module=cdi-decorate needs to be added to the command line, which can be done for a standard distribution by running the commands:

cd $JETTY_BASE
java -jar $JETTY_HOME/start.jar --add-to-start=cdi-decorate
Jetty cdi2 Module

Prior to Jetty-9.4.20 and Weld 3.1.2, the Weld/Jetty integration required some internal jetty APIs to be made visible to the web application. This can be done using the deprecated cdi2 module either by including --module=cdi2 on the command line or by running the commands:

cd $JETTY_BASE
java -jar $JETTY_HOME/start.jar --add-to-start=cdi2

If this module is not available in the jetty distribution you are using, then equivalent behaviour can be achieved by creating a jetty-web.xml descriptor (see also Jetty XML Reference):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
   <Call name="prependServerClass">
      <Arg>-org.eclipse.jetty.util.Decorator</Arg>
   </Call>
   <Call name="prependServerClass">
      <Arg>-org.eclipse.jetty.util.DecoratedObjectFactory</Arg>
   </Call>
   <Call name="prependServerClass">
      <Arg>-org.eclipse.jetty.server.handler.ContextHandler.</Arg>
   </Call>
   <Call name="prependServerClass">
      <Arg>-org.eclipse.jetty.server.handler.ContextHandler</Arg>
   </Call>
   <Call name="prependServerClass">
      <Arg>-org.eclipse.jetty.servlet.ServletContextHandler</Arg>
   </Call>
</Configure>
Tip
Directly modifying the web application classpath via jetty-web.xml will not work for Jetty-10.0.0 and later.
Jetty cdi-spi Module

Since Jetty-9.4.20 the Jetty cdi-spi module has been available that integrates any compliant CDI implementation by directly calling the CDI SPI. Since Weld support specific Jetty integration, it is not recommended to use this module with Weld.

Binding BeanManager to Jetty JNDI

To bind the BeanManager into JNDI, you should either populate WEB-INF/jetty-env.xml with the following contents:

<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"
   "http://www.eclipse.org/jetty/configure.dtd">

<Configure id="webAppCtx" class="org.eclipse.jetty.webapp.WebAppContext">
    <New id="BeanManager" class="org.eclipse.jetty.plus.jndi.Resource">
        <Arg> <Ref id="webAppCtx"/> </Arg>
        <Arg>BeanManager</Arg>
        <Arg>
            <New class="javax.naming.Reference">
                <Arg>javax.enterprise.inject.spi.BeanManager</Arg>
                <Arg>org.jboss.weld.resources.ManagerObjectFactory</Arg>
                <Arg/>
            </New>
        </Arg>
    </New>
</Configure>

Or you can configure a special Servlet listener to bind the BeanManager automatically:

<listener>
   <listener-class>org.jboss.weld.environment.servlet.BeanManagerResourceBindingListener</listener-class>
</listener>

You also need to make the BeanManager available to your deployment by adding this to the bottom of web.xml:

<resource-env-ref>
   <resource-env-ref-name>BeanManager</resource-env-ref-name>
   <resource-env-ref-type>
      javax.enterprise.inject.spi.BeanManager
   </resource-env-ref-type>
</resource-env-ref>

Jetty only allows you to bind entries to java:comp/env, so the BeanManager will be available at java:comp/env/BeanManager.

Embedded Jetty

When starting embedded Jetty programmatically from the main method it is necessary to register Weld’s listener:

public class Main {

    public static void main(String[] args) throws Exception {
        Server jetty = new Server(8080);
        WebAppContext context = new WebAppContext();
        context.setContextPath("/");
        context.setResourceBase("src/main/resources");
        jetty.setHandler(context);
        context.addServlet(HelloWorldServlet.class, "/*");

        context.addEventListener(new DecoratingListener()); # (1)
        context.addEventListener(new Listener()); # (2)

        jetty.start();
        jetty.join();
    }

    public static class HelloWorldServlet extends HttpServlet {

        @Inject BeanManager manager;

        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/plain");
            resp.getWriter().append("Hello from " + manager);
        }
    }
}
  1. Jetty’s org.eclipse.jetty.webapp.DecoratingListener registered programmatically (since Jetty-9.4.20)

  2. Weld’s org.jboss.weld.environment.servlet.Listener registered programmatically

Undertow

Weld supports context activation/deactivation and dependency injection into Servlets when running on Undertow. Injection into Filters and Servlet listeners is not currently supported. Weld’s listener needs to be registered programmatically:

public class Main {

    public static void main(String[] args) throws ServletException {
        DeploymentInfo servletBuilder = Servlets.deployment()
                .setClassLoader(Main.class.getClassLoader())
                .setResourceManager(new ClassPathResourceManager(Main.class.getClassLoader()))
                .setContextPath("/")
                .setDeploymentName("test.war")
                .addServlet(Servlets.servlet("hello", HelloWorldServlet.class).addMapping("/*"))

                .addListener(Servlets.listener(Listener.class)); # (1)

        DeploymentManager manager = Servlets.defaultContainer().addDeployment(servletBuilder);
        manager.deploy();

        HttpHandler servletHandler = manager.start();
        PathHandler path = Handlers.path(Handlers.redirect("/")).addPrefixPath("/", servletHandler);
        Undertow server = Undertow.builder().addHttpListener(8080, "localhost").setHandler(path).build();
        server.start();
    }

    public static class HelloWorldServlet extends HttpServlet {

        @Inject BeanManager manager;

        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/plain");
            resp.getWriter().append("Hello from " + manager);
        }
    }
}
  1. Weld’s org.jboss.weld.environment.servlet.Listener registered programmatically:

WildFly Web

WildFly Web is a lightweight Servlet container that uses Undertow. Weld supports context activation/deactivation and dependency injection into Servlets. Injection into Filters and Servlet listeners is not currently supported. Weld integration is started automatically when weld-servlet is part of your application.

Bean Archive Isolation

By default, bean archive isolation is enabled. It means that alternatives, interceptors and decorators can be selected/enabled for a bean archive by using a beans.xml descriptor.

This behaviour can be changed by setting the servlet initialization parameter org.jboss.weld.environment.servlet.archive.isolation to false. In this case, Weld will use a "flat" deployment structure - all bean classes share the same bean archive and all beans.xml descriptors are automatically merged into one. Thus alternatives, interceptors and decorators selected/enabled for a bean archive will be enabled for the whole application.

Note
Bean archive isolation is supported (and enabled by default) from version 2.2.5.Final. Previous versions only operated with the "flat" deployment structure.

Implicit Bean Archive Support

CDI 1.1 introduced the bean discovery mode of annotated used for implicit bean archives (see also Packaging and deployment . This mode may bring additional overhead during container bootstrap. Therefore, Weld Servlet supports the use of Jandex bytecode scanning library to speed up the scanning process. Simply put the jandex.jar on the classpath. If Jandex is not found on the classpath Weld will use the Java Reflection as a fallback.

In general, an implicit bean archive does not have to contain a beans.xml descriptor. However, such a bean archive is not supported by Weld Servlet, i.e. it’s excluded from discovery.

Note
The bean discovery mode of annotated is supported from version 2.2.5.Final. Previous versions processed implicit bean archives in the same way as explicit bean archives.

Servlet Container Detection

Weld servlet container integration is delivered as a single artifact, so that it’s possible to include this artifact in a war and deploy the application to any of the suported servlet containers. This approach has advantages but also drawbacks. One of them is the fact that Weld attempts to detect the servlet container automatically. While this works most of the time, there are few rare cases, when it might be necessary to specify the container manually by setting the servlet initialization parameter org.jboss.weld.environment.container.class to:

  • org.jboss.weld.environment.tomcat.TomcatContainer

  • org.jboss.weld.environment.jetty.JettyContainer

  • org.jboss.weld.environment.undertow.UndertowContainer

  • or any custom org.jboss.weld.environment.Container implementation

Java SE

In addition to improved integration of the Enterprise Java stack, the "Contexts and Dependency Injection for the Java EE platform" specification also defines a state of the art typesafe, stateful dependency injection framework, which can prove useful in a wide range of application types. To help developers take advantage of this, Weld provides a simple means for being executed in the Java Standard Edition (SE) environment independently of any Java EE APIs.

When executing in the SE environment the following features of Weld are available:

  • Managed beans with @PostConstruct and @PreDestroy lifecycle callbacks

  • Dependency injection with qualifiers and alternatives

  • @Application, @Dependent and @Singleton scopes

  • Interceptors and decorators

  • Stereotypes

  • Events

  • Portable extension support

EJB beans are not supported.

CDI SE Module

Weld provides an extension which will boot a CDI bean manager in Java SE, automatically registering all simple beans found on the classpath. The command line parameters can be injected using either of the following:

@Inject @Parameters List<String> params;
@Inject @Parameters String[] paramsArray;

The second form is useful for compatibility with existing classes.

Note
The command line parameters do not become available for injection until the ContainerInitialized event is fired. If you need access to the parameters during initialization you can do so via the public static String[] getParameters() method in StartMain.

Here’s an example of a simple CDI SE application:

import javax.inject.Singleton;

@Singleton
public class HelloWorld
{
   public void printHello(@Observes ContainerInitialized event, @Parameters List<String> parameters) {
       System.out.println("Hello " + parameters.get(0));
   }
}
Note
Weld automatically registers shutdown hook during initialization in order to properly terminate all running containers should the VM be terminated or program exited. Even though it’s possible to change this behavior (either by setting a system property org.jboss.weld.se.shutdownHook to false or through the Weld.property() method) and register an alternative hook and implement the logic, it is not recommended. The behavior across OS platforms may differ and specifically on Windows it proves to be problematic.

Bootstrapping CDI SE

CDI SE applications can be bootstrapped in the following ways.

The ContainerInitialized Event

Thanks to the power of CDI’s typesafe event model, application developers need not write any bootstrapping code. The Weld SE module comes with a built-in main method which will bootstrap CDI for you and then fire a ContainerInitialized event. The entry point for your application code would therefore be a simple bean which observes the ContainerInitialized event, as in the previous example.

In this case your application can be started by calling the provided main method like so:

java org.jboss.weld.environment.se.StartMain <args>
Programmatic Bootstrap API

For added flexibility, CDI SE also comes with a bootstrap API which can be called from within your application in order to initialize CDI and obtain references to your application’s beans and events. The API consists of two classes: Weld and WeldContainer.

/** A builder used to bootsrap a Weld SE container. */
public class Weld extends SeContainerInitializer implements ContainerInstanceFactory
{

   /** Boots Weld and creates and returns a WeldContainer instance, through which
    * beans and events can be accesed. */
   public WeldContainer initialize() {...}

   /** Convenience method for shutting down all the containers initialized by a specific builder instance. */
   public void shutdown() {...}

}
/** Represents a Weld SE container. */
public class WeldContainer extends AbstractCDI<Object> implements AutoCloseable, ContainerInstance, SeContainer
{

   /** Provides access to all events within the application. */
   public Event<Object> event() {...}

   /** Provides direct access to the BeanManager. */
   public BeanManager getBeanManager() {...}

   /** Returns the identifier of the container */
   String getId() {...}

   /** Shuts down the container. */
   public void shutdown() {...}

   /** Returns the running container with the specified identifier or null if no such container exists */
   public static WeldContainer instance(String id) {...}

}

Here’s an example application main method which uses this API to bootsrap a Wedl SE container and call a business method of a bean MyApplicationBean.

import org.jboss.weld.environment.se.Weld;

public static void main(String[] args) {
   Weld weld = new Weld();
   WeldContainer container = weld.initialize();
   container.select(MyApplicationBean.class).get().callBusinessMethod();
   container.shutdown();
}

Alternatively the application could be started by firing a custom event which would then be observed by another simple bean. The following example fires MyEvent on startup.

org.jboss.weld.environment.se.Weld;

public static void main(String[] args) {
   Weld weld = new Weld();
   WeldContainer container = weld.initialize();
   container.event().select(MyEvent.class).fire( new MyEvent() );
   // When all observer methods are notified the container shuts down
   container.shutdown();
}

Because WeldContainer implements AutoCloseable, it can be used within a try-with-resources block. Should the execution get out of the code block, the Weld instance is shut down and all managed instances are safely destroyed. Here is an example using the above code but leaving out the shutdown() method:

org.jboss.weld.environment.se.Weld;

public static void main(String[] args) {
   Weld weld = new Weld();
   try (WeldContainer container = weld.initialize()) {
      container.select(MyApplicationBean.class).get().callBusinessMethod();
   }
}

In case of more complex scenarios, it might be handy to gain higher level of control over the bootstraping process. Using the builder, it is possible to disable automatic scanning and to explicitly select classes/packages which will be managed by Weld. Interceptors, decorators and extensions can be defined in the very same manner. Last but not least, builder can be used to set Weld-specific configuration. Following example demonstrates these features:

Weld weld = new Weld()
    .disableDiscovery()
    .packages(Main.class, Utils.class)
    .interceptors(TransactionalInterceptor.class)
    .property("org.jboss.weld.construction.relaxed", true);

try (WeldContainer container = weld.initialize()) {
    MyBean bean = container.select(MyBean.class).get();
    System.out.println(bean.computeResult());
}

Furthermore, it is also possible to create several independent Weld instances. Code snippet below shows how to achieve that:

Weld weld = new Weld()
    .disableDiscovery();

weld.containerId("one").beanClasses(MyBean.class).initialize();
weld.containerId("two").beanClasses(OtherBean.class).initialize();

MyBean bean = WeldContainer.instance("one").select(MyBean.class).get();
System.out.println(bean.computeResult());

// Shutdown the first container
WeldContainer.instance("one").shutdown();

// Shutdown all the containers initialized by the builder instance
weld.shutdown();

Request Context

Weld introduces an @ActivateRequestContext interceptor binding which enables you to explicitly activate the request context and use @RequestScoped beans in Java SE. The following example shows how to achieve that:

public class Foo {

  @Inject
  MyRequestScopedBean bean;

  @ActivateRequestContext
  public void executeInRequestContext() {
    bean.ping()
  }

}

Thread Context

In contrast to Java EE applications, Java SE applications place no restrictions on developers regarding the creation and usage of threads. Therefore Weld SE provides a custom scope annotation, @ThreadScoped, and corresponding context implementation which can be used to bind bean instances to the current thread. It is intended to be used in scenarios where you might otherwise use ThreadLocal, and does in fact use ThreadLocal under the hood.

To use the @ThreadScoped annotation you need to enable the RunnableDecorator which 'listens' for all executions of Runnable.run() and decorates them by setting up the thread context beforehand, bound to the current thread, and destroying the context afterwards.

<beans>
  <decorators>
     <class>org.jboss.weld.environment.se.threading.RunnableDecorator</class>
  </decorator>
</beans>

Another option how to use thread context is to enable it at class or method level by @ActivateThreadScope interceptor binding and related ActivateThreadScopeInterceptor.

public class Foo {

  @Inject
  MyThreadScopedBean bean;

  @ActivateThreadScope
  public void executeInThreadContext() {
    bean.ping()
  }

}
Note
It is not necessary to use @ThreadScoped in all multithreaded applications. The thread context is not intended as a replacement for defining your own application-specific contexts. It is generally only useful in situations where you would otherwise have used ThreadLocal directly, which are typically rare.

Setting the Classpath

Weld SE comes packaged as a 'shaded' jar which includes the CDI API, Weld Core and all dependent classes bundled into a single jar. Therefore the only Weld jar you need on the classpath, in addition to your application’s classes and dependent jars, is the Weld SE jar. If you are working with a pure Java SE application you launch using java, this may be simpler for you.

If you prefer to work with individual dependencies, then you can use the weld-se-core jar which just contains the Weld SE classes. Of course in this mode you will need to assemble the classpath yourself.

If you work with a dependency management solution such as Maven you can declare a dependency such as:

<dependency>
   <groupId>org.jboss.weld.se</groupId>
   <artifactId>weld-se-shaded</artifactId>
</dependency>

Bean Archive Isolation

By default, bean archive isolation is enabled. It means that alternatives, interceptors and decorators can be selected/enabled for a bean archive by using a beans.xml descriptor.

This behaviour can be changed by setting a system property org.jboss.weld.se.archive.isolation to false or through the Weld.property() method. In this case, Weld will use a "flat" deployment structure - all bean classes share the same bean archive and all beans.xml descriptors are automatically merged into one. Thus alternatives, interceptors and decorators selected/enabled for a bean archive will be enabled for the whole application.

Note
Bean archive isolation is supported (and enabled by default) from version 2.2.0.Final. Previous versions only operated with the "flat" deployment structure.
Tip
All Weld SE specific configuration properties could be also set through CDI 2.0 API, i.e. using SeContainerInitializer.addProperty() and SeContainerInitializer.setProperties() methods.

Implicit Bean Archive Support

CDI 1.1 introduced the bean discovery mode of annotated used for implicit bean archives (see also Packaging and deployment . This mode may bring additional overhead during container bootstrap. Therefore, Weld Servlet supports the use of Jandex bytecode scanning library to speed up the scanning process. Simply put the jandex.jar on the classpath. If Jandex is not found on the classpath Weld will use the Java Reflection as a fallback.

By default, an implicit bean archive that does not contain a beans.xml descriptor is excluded from discovery. However, it is possible to instruct Weld to scan all class path entries and discover such archive. You can do so by setting Weld system property org.jboss.weld.se.scan.classpath.entries or CDI 2.0 system property javax.enterprise.inject.scan.implicit to true. Another approach is to use Weld.property() and SeContainerInitializer.addProperty() methods.

Note
The bean discovery mode of annotated is supported from version 2.2.0.Final. Previous versions processed implicit bean archives in the same way as explicit bean archives.

Extending Bean Defining Annotations

If you are running with discovery mode annotated, then only classes with bean defining annotations will be picked up as beans. The set of these annotations is given by CDI but Weld SE allows you to expand it via Weld.addBeanDefiningAnnotations(Class<? extends Annotation>…​ annotations). Any annotation added this way will be considered a bean defining annotation when performing discovery.

Just note that added annotations are ignored if you are also using <trim/> option or Weld configuration key org.jboss.weld.bootstrap.vetoTypesWithoutBeanDefiningAnnotation.

Weld SE and Weld Servlet cooperation

Sometimes it could be convenient to start Servlet container programmatically. In this case a cooperation with Weld SE might come handy. This cooperation is based on passing Weld, WeldContainer or BeanManager instance to ServletContextHandler (in case of Jetty). You can either set a context attribute or use org.jboss.weld.environment.servlet.Listener. Check following examples.

Adding WeldContainer instance as a context attribute:

        try (WeldContainer weld = new Weld().disableDiscovery().beanClasses(Cat.class).initialize()) {
              ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
              context.addEventListener(new Listener());
              context.setAttribute(Listener.CONTAINER_ATTRIBUTE_NAME, weld);

              Server server = new Server(8080);
              context.setContextPath("/");
              server.setHandler(context);
              context.addServlet(TestServlet.class, "/test");
              server.start();
        }

Adding BeanManager instance as a context attribute:

        Weld weld = new Weld();
        WeldContainer container = weld.initialize();

        Server server = new Server(8080);
        context.setContextPath("/");
        server.setHandler(context);
        context.addServlet(TestServlet.class, "/test");
        context.setAttribute(WeldServletLifecycle.BEAN_MANAGER_ATTRIBUTE_NAME, container.getBeanManager());
        server.start();

Adding Weld instance as event listener with usage of org.jboss.weld.environment.servlet.Listener:

        Weld builder = new Weld().disableDiscovery().beanClasses(Cat.class);
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.addEventListener(Listener.using(builder));

        Server server = new Server(8080);
        context.setContextPath("/");
        server.setHandler(context);
        context.addServlet(TestServlet.class, "/test");
        server.start();

OSGi

Weld supports OSGi environment through Pax CDI. For more information on using Weld in OSGi environment check Pax CDI documentation. If you wish to see some examples, there is plenty of them in Pax CDI repository.

Configuration

Weld configuration

Weld can be configured per application through the set of properties. All the supported configuration properties are described in the following subsections.

Each configuration property can be specified (by priority in descending order):

  1. In a properties file named weld.properties

  2. As a system property

  3. By a bootstrap configuration provided by an integrator

If a configuration key is set in multiple sources (e.g. as a system property and in a properties file), the value from the source with higher priority is taken, other values are ignored. Unsupported configuration keys are ignored. If an invalid configuration property value is set, the container automatically detects the problem and treats it as a deployment problem.

Relaxed construction

CDI requires that beans that are normal-scoped, intercepted or decorated always define a no-argument constructor. This requirement applies even if the bean already defines an @Inject annotated constructor with parameters. This is purely a technical requirement implied by how Java allocates class instances.

Weld is however able to operate fine even if this requirement is not met. Weld uses special non-portable JVM APIs that allow it to allocate proxy instances without calling proxy’s constructor. This mode is not enabled by default. It can be enabled using the following configuration option:

Table 1. Supported configuration properties
Configuration key Default value Description

org.jboss.weld.construction.relaxed

false (true in weld-se)

If set to true, then requirements on bean constructors are relaxed.

Note that relaxed construction is enabled by default in Weld SE .

Concurrent deployment configuration

By default Weld supports concurrent loading and deploying of beans. However, in certain deployment scenarios the default setup may not be appropriate.

Table 2. Supported configuration properties
Configuration key Default value Description

org.jboss.weld.bootstrap.concurrentDeployment

true

If set to false, ConcurrentDeployer and ConcurrentValidator will not be used.

org.jboss.weld.bootstrap.preloaderThreadPoolSize

Math.max(1, Runtime.getRuntime().availableProcessors() - 1)

Weld is capable of resolving observer methods for container lifecycle events in advance while bean deployer threads are blocked waiting for I/O operations (such as classloading). This process is called preloading and leads to better CPU utilization and faster application startup time. This configuration option specifies the number of threads used for preloading. If set to 0, preloading is disabled.

Note
The bootstrap configuration may be altered using the deprecated org.jboss.weld.bootstrap.properties file located on the classpath (e.g. WEB-INF/classes/org.jboss.weld.bootstrap.properties in a web archive). The keys are concurrentDeployment and preloaderThreadPoolSize.

Thread pool configuration

For certain types of tasks Weld uses its own thread pool. The thread pool is represented by the ExecutorServices service.

First of all, let’s see what types of thread pools are available:

Thread pool type Description

FIXED

Uses a fixed number of threads. The number of threads remains the same throughout the application.

FIXED_TIMEOUT

Uses a fixed number of threads. A thread will be stopped after a configured period of inactivity.

SINGLE_THREAD

A single-threaded thread pool

NONE

No executor is used by Weld

COMMON

The default ForkJoinPool.commonPool() is used by Weld. See link for more details

Now let’s see how to configure Weld to use a particular thread pool type:

Important
An integrator may choose to use custom implementation of org.jboss.weld.manager.api.ExecutorServices. If that’s the case, all configuration described in this section might be ignored. An example of such integrator is WildFly.
Table 3. Supported configuration properties
Configuration key Default value Description

org.jboss.weld.executor.threadPoolType

FIXED (COMMON in Weld SE)

The type of the thread pool. Possible values are: FIXED, FIXED_TIMEOUT, NONE, SINGLE_THREAD and COMMON

org.jboss.weld.executor.threadPoolSize

Runtime.getRuntime().availableProcessors()

The number of threads to be used for bean loading and deployment. Only used by FIXED and FIXED_TIMEOUT.

org.jboss.weld.executor.threadPoolKeepAliveTime

60 seconds

Passed to the constructor of the ThreadPoolExecutor class, maximum time that excess idle threads will wait for new tasks before terminating. Only used by FIXED_TIMEOUT.

org.jboss.weld.executor.threadPoolDebug

false

If set to true, debug timing information is printed to the standard output.

Note
It’s possible to alter the thread pool configuration using the deprecated org.jboss.weld.executor.properties file located on the classpath. The keys are threadPoolType, threadPoolSize, threadPoolKeepAliveTime and threadPoolDebug.

Non-portable mode during application initialization

By default the application initialization is performed in the portable mode which denotes specification-compliant behaviour. However it’s also possible to enable the non-portable mode, in which some definition errors and deployment problems do not cause application initialization to abort. Currently the non-portable mode allows extension developers to call all the BeanManager’s methods before the `AfterDeploymentValidation event is fired.

Table 4. Supported configuration properties
Configuration key Default value Description

org.jboss.weld.nonPortableMode

false

If set to true, the non-portable mode is enabled.

Note
The main purpose of the non-portable mode is to support some legacy extensions. It’s highly recommended to use the portable mode whenever possible - non-portable mode may lead to unexpected behaviour during initialization process.

Proxying classes with final methods

Weld offers a non-standard way to create proxies for non-private, non-static final methods. When using this option, such final method will be ignored during proxy generation and the Java type will be proxied (as opposed to classical behavior when there would be an exception thrown). Since the method was ignored during proxy creation, it should never be invoked.

In order to make this work, use the below shown configuration key and pass it a regular expression. When Weld finds an unproxyable type which matches this pattern, the final methods will be ignored and the type will be proxied.

Table 5. Supported configuration properties
Configuration key Default value Description

org.jboss.weld.proxy.ignoreFinalMethods

If defined, matching classes will be proxied and final methods ignored.

Bounding the cache size for resolved injection points

Weld caches already resolved injection points in order to resolve them faster in the future. A separate type-safe resolver exists for beans, decorators, disposers, interceptors and observers. Each of them stores resolved injection points in its cache, which maximum size is bounded by a default value (common to all of them).

Table 6. Supported configuration properties
Configuration key Default value Description

org.jboss.weld.resolution.cacheSize

65536

The upper bound of the cache.

Debugging generated bytecode

For debugging purposes, it’s possible to dump the generated bytecode of client proxies and enhanced subclasses to the filesystem.

Table 7. Supported configuration properties
Configuration key Default value Description

org.jboss.weld.proxy.dump

The file path where the files should be stored.

Injectable reference lookup optimization

For certain combinations of scopes, the container is permitted to optimize an injectable reference lookup. Enabling this feature brings some performance boost but causes javax.enterprise.context.spi.AlterableContext.destroy() not to work properly for @ApplicationScoped and @RequestScoped beans. Therefore, the optimization is disabled by default.

Table 8. Supported configuration properties
Configuration key Default value Description

org.jboss.weld.injection.injectableReferenceOptimization

false

If set to true, the optimization is enabled.

Bean identifier index optimization

This optimization is used to reduce the HTTP session replication overhead. However, the inconsistency detection mechanism may cause problems in some development environments. It’s recommended to disable this optimization during the development phase.

Table 9. Supported configuration properties
Configuration key Default value Description

org.jboss.weld.serialization.beanIdentifierIndexOptimization

true (false in weld-servlet)

If set to true, the optimization is enabled.

Note
This optimization is disabled by default in Servlet containers .

Rolling upgrades ID delimiter

Note
This configuration property should only be used if experiencing problems with rolling upgrades.

The delimiter is used to abbreviate a bean archive identifier (which is usually derived from the archive name) before used as a part of an identifier of an internal component (such as bean).

The abbreviation proceeds as follows:

  • Try to find the first occurrence of the specified delimiter

  • If not found, the identifier is not abbreviated

  • If found, try to extract the archive suffix (.war, .ear, etc.) and the final value consists of the part before the delimiter and the archive suffix (if extracted)

Note that the delimiter is used for all bean archives forming the application.

An example: Given an application with two versions going by the names test__1-1.war and test__1-2.war. Weld normally cannot support replication of @SessionScoped beans between these two deployments. Using this configuration option with delimiter "__" will allow Weld to see both applications simply as test.war, hence allowing for session replication.

Table 10. Supported configuration properties
Configuration key Default value Description

org.jboss.weld.clustering.rollingUpgradesIdDelimiter

The delimiter used during ID generation.

Warning
Bean archive identifiers are provided by integrators. Therefore, the abbreviation algorithm may not always function properly.

Development Mode

Some features of the development mode may have negative impact on the performance and/or functionality of the application. The following configuration properties allow to tune or disable these features, e.g. to specify the set of components which will be monitored.

Table 11. Supported configuration properties
Configuration key Tool Default value Description

org.jboss.weld.probe.invocationMonitor.excludeType

Probe

''

A regular expression. If a non-empty string and the base type for an AnnotatedType or a declaring type for an AnnotatedMember matches this pattern the type is excluded from monitoring.

org.jboss.weld.probe.invocationMonitor.skipJavaBeanProperties

Probe

'true'

If set to true, the JavaBean accessor methods are not monitored.

org.jboss.weld.probe.eventMonitor.excludeType

Probe

''

A regular expression. If a non-empty string and the runtime class of the event object matches this pattern the event is excluded from monitoring.

org.jboss.weld.probe.eventMonitor.containerLifecycleEvents

Probe

'false'

If set to true all the container lifecycle events are monitored during bootstrap.

org.jboss.weld.probe.embedInfoSnippet

Probe

'true'

If set to true an informative HTML snippet will be added to every HTTP response with Content-Type of value text/html.

org.jboss.weld.probe.jmxSupport

Probe

'false'

If set to true one or more MBean components may be registered so that it’s possible to use JMX to access the Probe development tool data.

org.jboss.weld.probe.exportDataAfterDeployment

Probe

''

If a non-empty string the Probe data will be automatically exported after deployment validation. The value represents the path of the directory where to export the data file.

Tip
To disable the monitoring entirely set org.jboss.weld.probe.invocationMonitor.excludeType and org.jboss.weld.probe.eventMonitor.excludeType properties to .*.

Conversation timeout and Conversation concurrent access timeout

Weld provides configuration properties to override values for default conversation timeout and default conversation concurrent access timeout which represents the maximum time to wait on the conversation concurrent lock.

Table 12. Supported configuration properties
Configuration key Default value (ms) Description

org.jboss.weld.conversation.timeout

600000

Conversation timeout represent the maximum time during which is the conversation active.

org.jboss.weld.conversation.concurrentAccessTimeout

1000

Conversation concurrent access timeout represent the maximum time to wait on the conversation concurrent lock.

Veto types without bean defining annotation

Sometimes it might be useful to process all types during bootstrap, i.e. fire/observe ProcessAnnotatedType event for each Java class discovered, but veto types which are not annotated with a bean defining annotation. The main reason is that not all classes that meet all of the necessary conditions are intended to become beans. And so vetoing such types helps to conserve memory used by the container. Note that if you use bean-discovey-mode=annotated (implicit bean archive) then no ProcessAnnotatedType will be fired for any such type because it’s not discovered at all. And there might be portable extensions which use ProcessAnnotatedType to extract some important information from classes which are not beans.

Therefore, Weld allows to use bean-discovey-mode=all (explicit bean archive) and veto types without a bean defining annotation whose AnnotatedType#getJavaClass().getName() matches a regular expression. In other words, a type is vetoed if its name matches a regular expression and at the same time is not annotated with a bean defining annotation. The functionality is implemented as a built-in portable extension processing all types from all bean archives.

Table 13. Supported configuration properties
Configuration key Default value Description

org.jboss.weld.bootstrap.vetoTypesWithoutBeanDefiningAnnotation

A regular expression. If a non-empty string, then all annotated types whose AnnotatedType#getJavaClass().getName() matches this pattern are vetoed if not annotated with a bean defining annotation.

Memory consumption optimization - removing unused beans

CDI applications consist of user-defined beans implementing the business logic, but also beans coming from libraries (e.g. DeltaSpike) and integrations (e.g. various Java EE technologies - JSF, Bean Validation, Batch). Most applications actually use only a small part of the beans provided by libraries and integrations. Still, Weld has to retain the metadata for all the beans in memory which can be considerably vast footprint, depending on the application. If Optimized cleanup after bootstrap is allowed, Weld can remove unused beans after bootstrap.

An unused bean:

  • is not excluded by the configuration properties described below,

  • is not a built-in bean, session bean, extension, interceptor or decorator,

  • does not have a name

  • does not declare an observer

  • is not eligible for injection to any injection point,

  • does not declare a producer which is eligible for injection to any injection point,

  • is not eligible for injection into any Instance<X> injection point.

Tip
If you run Probe and list all the beans in your application, you will almost certainly notice some of them coming from 3rd party libraries which you never use (marked with a trash icon). Those are candidates for unused beans as you can be sure you are not using them.
Note
As usual, there is a trade-off between memory consumption and bootstrap time. The results may vary depending on the application, but you should always expect (most probably negligible) increase of the bootstrap time.

The following properties can be used to restrict the set of beans Weld is going to remove, e.g. to eliminate the false positives.

Table 14. Supported configuration properties
Configuration key Default value Description

org.jboss.weld.bootstrap.unusedBeans.excludeType

ALL

A regular expression. A bean whose Bean#getBeanClass() matches this pattern is never removed. Two special values are considered. ALL (default value) means that all beans are excluded. NONE means no beans are excluded.

org.jboss.weld.bootstrap.unusedBeans.excludeAnnotation

javax\\.ws\\.rs.*

A regular expression. A bean is not removed if the corresponding AnnotatedType, or any member, is annotated with an annotation which matches this pattern. By default, a type annotated with any JAX-RS annotation is excluded from removal.

Defining external configuration

Weld allows integrators to provide an external configuration - a class which implements org.jboss.weld.configuration.spi.ExternalConfiguration interface. This interface has getConfigurationProperties method which returns a Map with provided configuration and also inherits a cleanup method because it extends org.jboss.weld.bootstrap.api.Service. Below is a short example of ExternalConfiguration implementation:

public class MyExternalConfiguration implements ExternalConfiguration {
    @Override
    public void cleanup() {
	// cleanup code
    }

    @Override
    public Map<String, Object> getConfigurationProperties() {
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(ConfigurationKey.CONCURRENT_DEPLOYMENT.get(), false);
        properties.put(ConfigurationKey.PRELOADER_THREAD_POOL_SIZE.get(), 200);
        properties.put(ConfigurationKey.PROXY_DUMP.get(), "/home/weld");
        return properties;
    }
}

Bear in mind that because ExternalConfiguration extends a Service it is required that any custom external configuration implementation is explicitly registered. See The Weld SPI for more information.

Last but not least external configuration is considered a source with the lowest priority which means that the properties specified there can be overriden by other sources such as system properties. For information on supported configuration keys, see Weld configuration. Also note that entries with unsupported properties will be ignored while invalid property values will lead to deployment problem.

Excluding classes from scanning and deployment

CDI 1.1 allows you to exclude classes in your archive from being scanned, having container lifecycle events fired, and being deployed as beans. See also 12.4.2 Exclude filters.

Note
Weld still supports the original non-portable way of excluding classes from discovery. The formal specification can be found in the xsd, located at http://jboss.org/schema/weld/beans_1_1.xsd. Unlike Weld, the CDI specification does not support regular expression patterns and ! character to invert the activation condition.

All the configuration is done in the beans.xml file. For more information see Packaging and deployment .

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee">

    <scan>

        <!-- Don't deploy the classes for the swing app! -->
        <exclude name="com.acme.swing.**" />

        <!-- Don't include GWT support if GWT is not installed -->
        <exclude name="com.acme.gwt.**">
            <if-class-not-available name="com.google.GWT"/>
        </exclude>

        <!--
            Exclude types from com.acme.verbose package if the system property verbosity is set to low
            i.e.
              java ... -Dverbosity=low
        -->
        <exclude name="com.acme.verbose.*">
            <if-system-property name="verbosity" value="low"/>
        </exclude>

        <!--
             Don't include JSF support if Wicket classes are present, and the viewlayer system
             property is set
        -->
        <exclude name="com.acme.jsf.**">
            <if-class-available name="org.apache.wicket.Wicket"/>
            <if-system-property name="viewlayer"/>
        </exclude>
    </scan>

</beans>

In this example we show the most common use cases for exercising fine control over which classes Weld scans. The first filter excludes all types whose package name starts with com.acme.swing, and in most cases this will be sufficient for your needs.

However, sometimes it’s useful to be able to activate the filter depending on the environment used. In this case, Weld allows you to activate (or deactivate) a filter based on either system properties or whether a class is available. The second filter shows the use case of disabling scanning of certain classes depending on the capabilities of the environment you deploy to - in this case we are excluding GWT support (all types whose package name starts with com.acme.gwt) if GWT is not installed.

Note
If you specify just a system property name, Weld will activate the filter if that system property has been set (with any value). If you also specify the system property value, then Weld will only activate the filter if the system property’s value matches exactly.

The third filter shows how to exclude all types from a specific package (note the name attribute has suffix ".*").

The fourth filter shows more a advanced configurations, where we use multiple activation conditions to decide whether to activate the filter.

You can combine as many activation conditions as you like (all must be true for the filter to be activated). If you want to a filter that is active if any of the activation conditions are true, then you need multiple identical filters, each with different activation conditions.

Mapping CDI contexts to HTTP requests

By default, CDI contexts are activated at the beginning of an HTTP request processing and deactivated once the processing finishes. This may represent an unnecessary overhead in certain situations, for example static resource serving.

Weld allows CDI context support to be mapped to a certain subset of requests only. A regular expression may be used for filtering HTTP requests that should have CDI contexts active during their processing.

<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

    <context-param>
        <param-name>org.jboss.weld.context.mapping</param-name>
        <param-value>.*\.html</param-value>
    </context-param>

</web-app>

Logging

Weld is using JBoss Logging, an abstraction layer 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.

The supported "back-end" frameworks include:

A system property org.jboss.logging.provider may be used to specify the logging framework directly. Supported values are jboss, jdk, log4j and slf4j. If this system property is not set, JBoss Logging will attempt to find the logging frameworks from the above-mentioned list on the classpath - the first one found is taken.

Java EE containers

If using Weld with a Java EE container (e.g. WildFly) the logging configuration is under the direction of the container. You should follow the container-specific guides to change the configuration (e.g. WildFly Admin Guide - Logging Configuration).

Servlet containers

Unlike the case of Java EE containers a web application deployed to a servlet container usually bundles a logging framework and possibly some configuration file. In this case, the configuration is in hands of the application developer (provided the bundled framework is supported by JBoss Logging).

If no logging framework is bundled follow the container-specific guides to change the configuration (e.g. Logging in Tomcat).

Weld SE

This is very similar to servlet containers except the class loading is usually even less complicated.

Tip

If you just want to see the debug log messages as quickly as possible in Weld SE try this:

  1. add org.slf4j:slf4j-simple on the classpath and remove other SLF4J bindings,

  2. set the "back-end" framework to slf4j,

  3. and change the level for org.jboss.weld, e.g.:

    mvn clean test -Dtest=MyWeldSETest -Dorg.jboss.logging.provider=slf4j -Dorg.slf4j.simpleLogger.log.org.jboss.weld=debug

WeldManager interface

WeldManager is an enhanced version of BeanManager which contains several additional methods. While some of them are designed to be used by integrators such as WildFly, others can be handy for users writing their CDI applications. Beginning with 3.1.0.Final, there is a built-in bean provided so that you can easily obtain it via @Inject WeldManager.

Here is a list of methods that this interface offers on top of what you can find in BeanManager:

public interface WeldManager extends BeanManager {

    <T> InjectionTarget<T> createInjectionTarget(EjbDescriptor<T> descriptor);
    <T> Bean<T> getBean(EjbDescriptor<T> descriptor);
    <T> EjbDescriptor<T> getEjbDescriptor(String ejbName);
    ServiceRegistry getServices();
    <X> InjectionTarget<X> fireProcessInjectionTarget(AnnotatedType<X> type);
    <X> InjectionTarget<X> fireProcessInjectionTarget(AnnotatedType<X> annotatedType, InjectionTarget<X> injectionTarget);
    String getId();
    Instance<Object> instance();
    <T> WeldInjectionTargetFactory<T> getInjectionTargetFactory(AnnotatedType<T> type);
    <T> WeldCreationalContext<T> createCreationalContext(Contextual<T> contextual);
    Bean<?> getPassivationCapableBean(BeanIdentifier identifier);
    <T> WeldInjectionTargetBuilder<T> createInjectionTargetBuilder(AnnotatedType<T> type);
    WeldManager unwrap();
    <T> AnnotatedType<T> createAnnotatedType(Class<T> type, String id);
    <T> void disposeAnnotatedType(Class<T> type, String id);
    boolean isContextActive(Class<? extends Annotation> scopeType);
    Collection<Class<? extends Annotation>> getScopes();
    Collection<Context> getActiveContexts();
    Collection<WeldAlterableContext> getActiveWeldAlterableContexts();
}

Please refer to the JavaDoc in the API to see what each method does.

Development Mode

Weld comes with a special mode for application development. When enabled, certain built-in tools which facilitate the development of CDI applications, are available.

Note
The development mode should not be used in production as it may have negative impact on the performance of the application. Make sure to disable the development mode before deploying to production.
Warning
Not all environments and containers may support the development mode and all tools. Check the tools details and the container documentation.

How to enable the development mode

Web application

For a web application, set the Servlet initialization parameter org.jboss.weld.development to true:

<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

    <context-param>
        <param-name>org.jboss.weld.development</param-name>
        <param-value>true</param-value>
    </context-param>

</web-app>
Note
An integrator is allowed to specify an alternative way of enabling the development mode. See for example WildFly Documentation.

Weld SE

For a Java SE application, set the system property org.jboss.weld.development to true:

java -cp myCoolApp.jar -Dorg.jboss.weld.development=true com.foo.MyMain

or use the Weld.enableDevMode() method:

org.jboss.weld.environment.se.Weld;

public static void main(String[] args) {
   try (WeldContainer container = new Weld().enableDevMode().initialize()) {
      ...
   }
}

Is The Development Mode Enabled?

You should see the following log message during initialization of your application:

=====================================
 Weld Development Mode: ENABLED
 ------------------------------------
 Disable this mode in production - it may have negative impact on performance and/or represent a potential security risk
=====================================

Development Tools

Probe

This tool allows you to inspect the application CDI components at runtime. There is a default UI - HTML client (single-page application), which is only available in web applications. Just point your browser to protocol://host:port/webappContextPath/weld-probe, e.g. http://localhost:8080/weld-numberguess/weld-probe. However, it’s also posible to obtain the JSON data through the REST API, eventually (if JMX support is enabled ) through the MXBean of name org.jboss.weld.probe:type=JsonData,context=ID where ID should be replaced with an idenfitier of an application. Right now, Probe integration is provided for WildFly, Tomcat and Jetty (Weld Servlet), and Weld SE.

Tip
There are some configuration properties which allow to tune or disable Probe features, e.g. to restrict the set of components which will be monitored. See also Development Mode .

Validation Report

If a deployment validation fails and the development mode is enabled a simple HTML report is generated. The report contains a lot of useful information such as Weld version, list of enabled beans, list of bean archives, Weld configuration, etc. By default, the report is generated to the user’s current working directory, ie. user.dir. However, it is also possible to specify a path to the target directory using the org.jboss.weld.probe.exportDataAfterDeployment configuration property - see also Development Mode .

You should see a similar log message which contains the path to the report file:

=====================================
 Weld - Deployment Validation: FAILED
 ------------------------------------
 HTML report generated to:

 file:///path/to/report/weld-validation-report.html
=====================================
Tip
We encourage you to always attach this report when asking a question on the mailing list or any other communication channel.

Context Management

Managing the built in contexts

Weld allows you to easily manage the built in contexts by injecting them and calling lifecycle methods. Weld defines two types of context, managed and unmanaged. Managed contexts can be activated (allowing bean instances to be retrieved from the context), invalidated (scheduling bean instances for destruction) and deactivated (stopping bean instances from being retrieved, and if the context has been invalidated, causing the bean instances to be destroyed). Unmanaged contexts are always active; some may offer the ability to destroy instances.

Managed contexts can either be bound or unbound. An unbound context is scoped to the thread in which it is activated (instances placed in the context in one thread are not visible in other threads), and is destroyed upon invalidation and deactivation. Bound contexts are attached to some external data store (such as the HTTP Session or a manually propagated map) by associating the data store with the context before calling activate, and dissociating the data store after calling activate.

Tip
Weld automatically controls context lifecycle in many scenarios such as HTTP requests, EJB remote invocations, and MDB invocations. Many of the extensions for CDI offer context lifecycle for other environments, it’s worth checking to see if there is a suitable extension before deciding to manage the context yourself.

Weld provides a number of built in contexts, which are shown in Available Contexts in Weld.

Table 15. Available Contexts in Weld
Scope Qualifiers Context Notes

@Dependent

@Default

DependentContext

The dependent context is unbound and unmanaged

@RequestScoped

@Unbound

RequestContext

An unbound request context, useful for testing

@RequestScoped

@Bound

@Default

RequestContext

BoundRequestContext

A request context bound to a manually propagated map, useful for testing or non-Servlet environments

@RequestScoped

@Http

@Default

RequestContext

HttpRequestContext

A request context bound to a Servlet request, used for any Servlet based request context

@RequestScoped

@Ejb

@Default

RequestContext

EjbRequestContext

A request context bound to a an interceptor’s invocation context, used for EJB invocations outside of Servlet requests

@ConversationScoped

@Bound

@Default

ConversationContext

BoundConversationContext

A conversation context bound to two manually propagated maps (one which represents the request and one which represents the session), useful for testing or non-Servlet environments

@ConversationScoped

@Http

@Default

ConversationContext

HttpConversationContext

A conversation context bound to a Servlet request, used for any Servlet based conversation context

@SessionScoped

@Bound

@Default

SessionContext

BoundSessionContext

A session context bound to a manually propagated map, useful for testing or non-Servlet environments

@SessionScoped

@Http

@Default

SessionContext

HttpSessionContext

A session context bound to a Servlet request, used for any Servlet based session context

@ApplicationScoped

@Default

ApplicationContext

An application context backed by an application scoped singleton, it is unmanaged and unbound but does offer an option to destroy all entries

@SingletonScoped

@Default

SingletonContext

A singleton context backed by an application scoped singleton, it is unmanaged and unbound but does offer an option to destroy all entries

Unmanaged contexts offer little of interest in a discussion about managing context lifecycles, so from here on in we will concentrate on the managed contexts (unmanaged contexts of course play a vital role in the functioning of your application and Weld!). As you can see from the table above, the managed contexts offer a number of different implementations for the same scope; in general, each flavor of context for a scope has the same API. We’ll walk through a number of common lifecycle management scenarios below; armed with this knowledge, and the Javadoc, you should be able to work with any of the context implementations Weld offers.

We’ll start simple with the BoundRequestContext, which you might use to provide the request scope outside of a Servlet request or EJB Invocation.

   /* Inject the BoundRequestContext. */
   /* Alternatively, you could look this up from the BeanManager */
   @Inject BoundRequestContext requestContext;

   ...

   /* Start the request, providing a data store which will last the lifetime of the request */
   public void startRequest(Map<String, Object> requestDataStore) {
      // Associate the store with the context and activate the context
      requestContext.associate(requestDataStore);
      requestContext.activate();
   }

   /* End the request, providing the same data store as was used to start the request */
   public void endRequest(Map<String, Object> requestDataStore) {
      try {
         /* Invalidate the request (all bean instances will be scheduled for destruction) */
         requestContext.invalidate();
         /* Deactivate the request, causing all bean instances to be destroyed (as the context is invalid) */
         requestContext.deactivate();
      } finally {
         /* Ensure that whatever happens we dissociate to prevent any memory leaks */
         requestContext.dissociate(requestDataStore);
      }
   }

The bound session context works in much the same way, excepting that invalidating and deactivating the session context causes the any conversations in the session to be destroyed as well. The HTTP session context and HTTP request context also work similarly, and might be of use if you find yourself creating threads from an HTTP request). The HTTP session context additionally offers a method which can immediately destroy the context.

Note
Weld’s session contexts are "lazy" and don’t require a session to actually exist until a bean instance must be written.

The conversation context offers a few more options, which we will walk through here.

   @Inject BoundConversationContext conversationContext;

   ...

   /* Start a transient conversation */
   /* Provide a data store which will last the lifetime of the request */
   /* and one that will last the lifetime of the session */
   public void startTransientConversation(Map<String, Object> requestDataStore,
                                          Map<String, Object> sessionDataStore) {
      resumeOrStartConversation(requestDataStore, sessionDataStore, null);
   }

   /* Start a transient conversation (if cid is null) or resume a non-transient */
   /* conversation. Provide a data store which will last the lifetime of the request */
   /* and one that will last the lifetime of the session */
   public void resumeOrStartConversation(Map<String, Object> requestDataStore,
                                         Map<String, Object> sessionDataStore,
                                         String cid) {
      /* Associate the stores with the context and activate the context */
      * BoundRequest just wraps the two datastores */
      conversationContext.associate(new MutableBoundRequest(requestDataStore, sessionDataStore));
      // Pass the cid in
      conversationContext.activate(cid);
   }

   /* End the conversations, providing the same data store as was used to start */
   /* the request. Any transient conversations will be destroyed, any newly-promoted */
   /* conversations will be placed into the session */
   public void endOrPassivateConversation(Map<String, Object> requestDataStore,
                                          Map<String, Object> sessionDataStore) {
      try {
         /* Invalidate the conversation (all transient conversations will be scheduled for destruction) */
         conversationContext.invalidate();
         /* Deactivate the conversation, causing all transient conversations to be destroyed */
         conversationContext.deactivate();
      } finally {
        /* Ensure that whatever happens we dissociate to prevent memory leaks*/
         conversationContext.dissociate(new MutableBoundRequest(requestDataStore, sessionDataStore));
      }
   }

The conversation context also offers a number of properties which control the behavior of conversation expiration (after this period of inactivity the conversation will be ended and destroyed by the container), and the duration of lock timeouts (the conversation context ensures that a single thread is accessing any bean instances by locking access, if a lock can’t be obtained after a certain time Weld will error rather than continue to wait for the lock). Additionally, you can alter the name of the parameter used to transfer the conversation id (by default, cid).

Weld also introduces the notion of a ManagedConversation, which extends the Conversation interface with the ability to lock, unlock and touch (update the last used timestamp) a conversation. Finally, all non-transient conversations in a session can be obtained from the conversation context, as can the current conversation.

Note
Weld’s conversations are not assigned ids until they become non-transient.

Propagating built-in contexts

By context propagation we understand a scenario in which you want to capture a collection of contextual instances bound to certain context in one thread and provide them as context state in another thread. Starting with Weld 3.1.0.Final, this kind of context propagation is possible.

Note
Context propagation comes with some additional requirements on user code and may not work for every scenario!

First of all, what contexts are affected and how:

  • Application context

    • Works out of the box, no propagation needed

  • Singleton context

    • Works out of the box, no propagation needed

  • Dependent context

    • By nature of this context, this cannot be propagated

  • Request, session, conversation contexts

    • These can be manually propagated if desired

In order to achieve context propagation you generally need the following steps:

  • Obtain collection of contextual instances from current thread

  • In another thread, obtain a reference to given context and activate it

  • Feed this newly activated context the instances you previously obtained

  • Perform your tasks

  • Clean up the context by deactivating it

New API methods supporting context propagation

There are several new things in Weld API allowing for this. Firstly, all contexts supporting propagation now implement org.jboss.weld.context.WeldAlterableContext, an interface extending javax.enterprise.context.spi.AlterableContext. Methods on WeldAlterableContext allow to capture current context state, returning a collection of all contextual instances, as well as clear and set the context state by feeding it a collection of contextual instances.

public interface WeldAlterableContext extends AlterableContext {
    default <T> Collection<ContextualInstance<T>> getAllContextualInstances();
    default <T> void clearAndSet(Collection<ContextualInstance<T>> setOfInstances);
}

In order to get hold of these contexts, the best approach is to use WeldManager, an injectable bean providing some capabilities on top of what BeanManager has. Following WeldManager methods are useful for context propagation:

public interface WeldManager extends BeanManager {

    // excerpt of interface methods is shortened here
    boolean isContextActive(Class<? extends Annotation> scopeType);
    Collection<Class<? extends Annotation>> getScopes();
    default Collection<Context> getActiveContexts() {
        return getScopes().stream()
            .filter(this::isContextActive)
            .map(this::getContext)
            .collect(Collectors.toSet());
    }
    default Collection<WeldAlterableContext> getActiveWeldAlterableContexts() {
        return getScopes().stream()
            .filter(this::isContextActive)
            .map(this::getContext)
            .filter(t -> t instanceof WeldAlterableContext)
            .map(t -> (WeldAlterableContext) t)
            .collect(Collectors.toSet());
    }
}

Example of context propagation

There is a concise example in a form of a test in our code showing how to propagate all built-in contexts. This doc only contains an excerpt from it, you can look here to get the full picture.

Following code shows a service that provides an extra thread onto which you offload a Callable<T> that uses beans from currently active context. The service activates contexts, propagates state from original thread, executes task and cleans up. Bound versions of Weld context implementations are used as on this new thread there is no actual HTTP request or session existing.

public class ContextPropagationService {

    private static final ExecutorService executor = Executors.newFixedThreadPool(1);

    public static <T> Future<T> propagateContextsAndSubmitTask(Callable<T> task) {
        // gather all the contexts we want to propagate and the instances in them
        Map<Class<? extends Annotation>, Collection<ContextualInstance<Object>>> scopeToContextualInstances = new HashMap<>();
        WeldManager get = CDI.current().select(WeldManager.class).get();
        for (WeldAlterableContext context : CDI.current().select(WeldManager.class).get().getActiveWeldAlterableContexts()) {
            scopeToContextualInstances.put(context.getScope(), context.getAllContextualInstances());
        }
        // We create a task wrapper which will make sure we have contexts propagated
        Callable<T> wrappedTask = new Callable<T>() {

            @Override
            public T call() throws Exception {
                // Get WeldManager,get instances of @Bound contexts for request, session and conversation scopes
                WeldManager weldManager = CDI.current().select(WeldManager.class).get();
                BoundRequestContext requestContext = weldManager.instance().select(BoundRequestContext.class, BoundLiteral.INSTANCE).get();
                BoundSessionContext sessionContext = weldManager.instance().select(BoundSessionContext.class, BoundLiteral.INSTANCE).get();
                BoundConversationContext conversationContext = weldManager.instance().select(BoundConversationContext.class, BoundLiteral.INSTANCE).get();

                // We will be using bound contexts, prepare backing structures for contexts
                Map<String, Object> sessionMap = new HashMap<>();
                Map<String, Object> requestMap = new HashMap<>();
                BoundRequest boundRequest = new MutableBoundRequest(requestMap, sessionMap);

                // activate contexts
                requestContext.associate(requestMap);
                requestContext.activate();
                sessionContext.associate(sessionMap);
                sessionContext.activate();
                conversationContext.associate(boundRequest);
                conversationContext.activate();

                // propagate all contexts that have some bean in them
                if (scopeToContextualInstances.get(requestContext.getScope()) != null) {
                    requestContext.clearAndSet(scopeToContextualInstances.get(requestContext.getScope()));
                }
                if (scopeToContextualInstances.get(sessionContext.getScope()) != null) {
                    sessionContext.clearAndSet(scopeToContextualInstances.get(sessionContext.getScope()));
                }
                if (scopeToContextualInstances.get(conversationContext.getScope()) != null) {
                    conversationContext.clearAndSet(scopeToContextualInstances.get(conversationContext.getScope()));
                }

                // now execute the actual original task
                T result = task.call();

                // cleanup, context deactivation, do not trigger @PreDestroy/@Disposes
                requestContext.deactivate();
                conversationContext.deactivate();
                sessionContext.deactivate();

                // all done, return
                return result;
            }
        };
        return executor.submit(wrappedTask);
    }
}

Pitfalls and drawbacks

There are several things that can possibly go wrong when propagating contexts. User code needs to be aware that propagation can happen and prepare their beans accordingly. For instance request scoped beans could now theoretically be accessed concurrently which wasn’t the case before.

@PreDestroy and @Disposes on your beans could cause inconsistent state based on how you perform the propagation. Since the same bean is now used in several threads, all of them can, in invalidating and deactivating contexts, trigger these methods but the bean will still exist in yet another thread. The example given above avoids calling context.invalidate() and only performs context.deactivate() - this avoids invoking @PreDestroy/@Disposes methods but could possibly lead to never invoking them if no thread does it. Note that this problem only concerns request, session and conversation beans where you manually need to activate/deactivate contexts. Application/singleton scoped bean would still work and their cleanup callbacks will only be invoked once during container shutdown.

There is currently no way to propagate any other contexts than those mentioned here. Custom scopes as well as scopes from other EE specifications have no support for this feature. The reason is that while technically any context implementing WeldAlterableContext can be used to obtain/set collection of contextual instances, there is no way of knowing how to activate custom contexts in different threads.

Last but not least, context propagator needs to be aware of context implementations existing in Weld, see Available Contexts in Weld. However, in a new thread some extra knowledge is required to activate the contexts. Bound versions (backed by a provided storage; a map in our case) were used, and those need to have a storage associated before activating them, hence the code such as requestContext.associate(requestMap). There is no need to use bound version though; propagators are free to choose from other context implementations.

Appendix A: Integrating Weld into other environments

If you want to use Weld in another environment, you will need to provide certain information to Weld via the integration SPI. In this Appendix we will briefly discuss the steps needed.

If you are upgrading existing Weld integration to work with Weld 3, see Migration from Weld 2.4 to 3.0.

Note
If you just want to use managed beans, and not take advantage of enterprise services (EE resource injection, CDI injection into EE component classes, transactional events, support for CDI services in EJBs) and non-flat deployments, then the generic servlet support provided by the "Weld: Servlets" extension will be sufficient, and will work in any container supporting the Servlet API.

All SPIs and APIs described have extensive JavaDoc, which spell out the detailed contract between the container and Weld.

The Weld SPI

The Weld SPI is located in the weld-spi module, and packaged as weld-spi.jar. Some SPIs are optional, and should only be implemented if you need to override the default behavior; others are required.

All interfaces in the SPI support the decorator pattern and provide a Forwarding class located in the helpers sub package. Additional, commonly used, utility classes, and standard implementations are also located in the helpers sub package.

Weld supports multiple environments. An environment is defined by an implementation of the Environment interface. A number of standard environments are built in, and described by the Environments enumeration. Different environments require different services to be present. For example a Servlet container doesn’t require transaction, EJB or JPA services.

Weld uses services to communicate with its environment. A service is a java class that implements the org.jboss.weld.bootstrap.api.Service interface and is explicitly registered. A service may be BDA-specific or may be shared across the entire application.

public interface Service {
   public void cleanup();
}

Certain services are only used at bootstrap and need to be cleaned up afterwards in order not to consume memory. A service that implements the specialized org.jboss.weld.bootstrap.api.BootstrapService interface receives a cleanupAfterBoot() method invocation once Weld initialization is finished but before the deployment is put into service.

public interface BootstrapService extends Service {
    void cleanupAfterBoot();
}

Weld uses a generic-typed service registry to allow services to be registered. All services implement the Service interface. The service registry allows services to be added and retrieved.

Deployment structure

An application is often comprised of a number of modules. For example, a Java EE deployment may contain a number of EJB modules (containing business logic) and war modules (containing the user interface). A container may enforce certain accessibility rules which limit the visibility of classes between modules. CDI allows these same rules to apply to bean and observer method resolution. As the accessibility rules vary between containers, Weld requires the container to describe the deployment structure, via the Deployment SPI.

The CDI specification discusses Bean Archives (BAs)—archives which are marked as containing beans which should be deployed to the CDI container, and made available for injection and resolution. Weld reuses this description and uses Bean Deployment Archives (BDA) in its deployment structure SPI.

Each deployment exposes the containing BDAs that form a graph. A node in the graph represents a BDA. Directed edges between nodes designate visibility. Visibility is not transitive (i.e. a bean from BDA A can only see beans in BDAs with which A is directly connected by a properly oriented edge).

To describe the deployment structure to Weld, the container should provide an implementation of Deployment. Deployment.getBeanDeploymentArchives() allows Weld to discover the modules which make up the application. The CDI specification also allows beans to be specified programmatically as part of the bean deployment. These beans may, or may not, be in an existing BDA. For this reason, Weld will call Deployment.loadBeanDeploymentArchive(Class clazz) for each programmatically described bean.

As programmatically described beans may result in additional BDAs being added to the graph, Weld will discover the BDA structure every time an unknown BDA is returned by Deployment.loadBeanDeploymentArchive.

Note

In a strict container, each BDA might have to explicitly specify which other BDAs it can access. However many containers will allow an easy mechanism to make BDAs bi-directionally accessible (such as a library directory). In this case, it is allowable (and reasonable) to describe all such archives as a single, 'virtual' BeanDeploymentArchive.

A container, might, for example, use a flat accessibility structure for the application. In this case, a single BeanDeploymentArchive would be attached to the Deployment.

BeanDeploymentArchive provides three methods which allow it’s contents to be discovered by Weld—BeanDeploymentArchive.getBeanClasses() must return all the classes in the BDA, BeanDeploymentArchive.getBeansXml() must return a data structure representing the beans.xml deployment descriptor for the archive, and BeanDeploymentArchive.getEjbs() must provide an EJB descriptor for every EJB in the BDA, or an empty list if it is not an EJB archive.

To aid container integrator, Weld provides a built-in beans.xml parser. To parse a beans.xml into the data-structure required by BeanDeploymentArchive, the container should call Bootstrap.parse(URL). Weld can also parse multiple beans.xml files, merging them to become a single data-structure. This can be achieved by calling Bootstrap.parse(Iterable<URL>).

When multiple beans.xml files are merged, Weld keeps duplicate enabled entries (interceptors, decorators or alternatives). This may cause validation problems when multiple physical archives which define an overlapping enabled entries are merged. A version of the Bootstrap.parse() method that provides control over whether duplicate enabled entries are remove or not is provided: Bootstrap.parse(Iterable<URL> urls, boolean removeDuplicates).

BDA X may also reference another BDA Y whose beans can be resolved by, and injected into, any bean in BDA X. These are the accessible BDAs, and every BDA that is directly accessible by BDA X should be returned. A BDA will also have BDAs which are accessible transitively, and the transitive closure of the sub-graph of BDA X describes all the beans resolvable by BDA X.

Note
In practice, you can regard the deployment structure represented by Deployment, and the virtual BDA graph as a mirror of the classloader structure for a deployment. If a class can from BDA X can be loaded by another in BDA Y, it is accessible, and therefore BDA Y’s accessible BDAs should include BDA X.

To specify the directly accessible BDAs, the container should provide an implementation of BeanDeploymentArchive.getBeanDeploymentArchives().

Note
Weld allows the container to describe a circular graph, and will convert a graph to a tree as part of the deployment process.

Certain services are provided for the whole deployment, whilst some are provided per-BDA. BDA services are provided using BeanDeploymentArchive.getServices() and only apply to the BDA on which they are provided.

The contract for Deployment requires the container to specify the portable extensions (see chapter Packaging and deployment of the CDI specification) which should be loaded by the application. To aid the container integrator, Weld provides the method Bootstrap.loadExtensions(ClassLoader) which will load the extensions for the specified classloader.

EE Modules

In Java EE environment, description of each Java EE module that contains bean archives deployment should be provided. This applies to:

  • web modules (wars)

  • EJB modules

  • connector modules (rar)

  • application client modules

  • enterprise archive libraries (ear/lib)

For each such module the integrator should create an instance of the EEModuleDescriptor which describes the module. EEModuleDescriptorImpl is provided for convenience.

An EEModuleDescriptor instance that represents a given module should be registered as a per bean archive service in each BeanDeploymentArchive that belongs to the given module. This applies both to physical bean archives deployed within the given module and also to logical bean archives that belong to the module. Bean archives that are not part of a Java EE module (e.g. built-in server libraries) are not required to have a EEModuleDescriptor service registered.

EJB descriptors

Weld delegates EJB 3 bean discovery to the container so that it doesn’t duplicate the work done by the EJB container, and respects any vendor-extensions to the EJB definition.

The EjbDescriptor should return the relevant metadata as defined in the EJB specification. Each business interface of a session bean should be described using a BusinessInterfaceDescriptor.

By default, Weld uses the EJB component class when creating new EJB instances. This may not always be desired especially if the EJB container uses subclassing internally. In such scenario, the EJB container requires that the subclass it generated is used for creating instances instead of the component class. An integrator can communicate such layout to Weld by additionally implementing the optional SubclassedComponentDescriptor interface in the EjbDescriptor implementation. The return value of the SubclassedComponentDescriptor.getComponentSubclass() method determines which class will be used by Weld when creating new EJB instances.

EE resource injection and resolution services

All the EE resource services are per-BDA services, and may be provided using one of two methods. Which method to use is at the discretion of the integrator.

The integrator may choose to provide all EE resource injection services themselves, using another library or framework. In this case the integrator should use the EE environment, and implement the Injection Services SPI.

Alternatively, the integrator may choose to use CDI to provide EE resource injection. In this case, the EE_INJECT environment should be used, and the integrator should implement the EJB services, Resource Services and JPA services.

Important
CDI only provides annotation-based EE resource injection; if you wish to provide deployment descriptor (e.g. ejb-jar.xml) injection, you must use Injection Services.

If the container performs EE resource injection, the injected resources must be serializable. If EE resource injection is provided by Weld, the resolved resource must be serializable.

Tip
If you use a non-EE environment then you may implement any of the EE service SPIs, and Weld will provide the associated functionality. There is no need to implement those services you don’t need!

Weld registers resource injection points with EjbInjectionServices, JpaInjectionServices, ResourceInjectionServices and JaxwsInjectionServices implementations upfront (at bootstrap). This allows validation of resource injection points to be performed at boot time rather than runtime. For each resource injection point Weld obtains a ResourceReferenceFactory which it then uses at runtime for creating resource references.

public interface ResourceReferenceFactory<T> {
    ResourceReference<T> createResource();
}

A ResourceReference provides access to the resource reference to be injected. Furthermore, ResourceReference allows resource to be release once the bean that received resource injection is destroyed.

public interface ResourceReference<T> {
    T getInstance();
    void release();
}

EJB services

EJB services are split between two interfaces which are both per-BDA.

EjbServices is used to resolve local EJBs used to back session beans, and must always be provided in an EE environment. EjbServices.resolveEjb(EjbDescriptor ejbDescriptor) returns a wrapper—SessionObjectReference—around the EJB reference. This wrapper allows Weld to request a reference that implements the given business interface, and, in the case of SFSBs, both request the removal of the EJB from the container and query whether the EJB has been previously removed.

EjbInjectionServices.registerEjbInjectionPoint(InjectionPoint injectionPoint) registers an @EJB injection point (on a managed bean) and returns a ResourceReferenceFactory as explained above. This service is not required if the implementation of Injection Services takes care of @EJB injection.

Note
EJBInjectionServices.resolveEjb(InjectionPoint ij), which allows @EJB injection point to be resolved without prior registration was deprecated in Weld 2 and should no longer be used. An injection point should be registered properly using EjbInjectionServices.registerEjbInjectionPoint(InjectionPoint injectionPoint) instead.

JPA services

Just as EJB resolution is delegated to the container, resolution of @PersistenceContext for injection into managed beans (with the InjectionPoint provided), is delegated to the container.

To allow JPA integration, the org.jboss.weld.injection.spi.JpaInjectionServices interface should be implemented. This service is not required if the implementation of Injection Services takes care of @PersistenceContext injection.

Note

The following methods were deprecated in Weld 2:

* JpaInjectionServices.resolvePersistenceContext(InjectionPoint injectionPoint)

* JpaInjectionServices.resolvePersistenceUnit(InjectionPoint injectionPoint)

An injection point should instead be registered properly using the following methods:

* JpaInjectionServices.registerPersistenceContextInjectionPoint(InjectionPoint injectionPoint) * JpaInjectionServices.registerPersistenceUnitInjectionPoint(InjectionPoint injectionPoint)

Transaction Services

Weld delegates JTA activities to the container. The SPI provides a couple hooks to easily achieve this with the TransactionServices interface.

Any javax.transaction.Synchronization implementation may be passed to the registerSynchronization() method and the SPI implementation should immediately register the synchronization with the JTA transaction manager used for the EJBs.

To make it easier to determine whether or not a transaction is currently active for the requesting thread, the isTransactionActive() method can be used. The SPI implementation should query the same JTA transaction manager used for the EJBs.

Resource Services

The resolution of @Resource (for injection into managed beans) is delegated to the container. You must provide an implementation of ResourceInjectionServices which provides these operations. This service is not required if the implementation of Injection Services takes care of @Resource injection.

Note

The following methods were deprecated in Weld 2:

* ResourceInjectionServices.resolveResource(InjectionPoint injectionPoint)

* ResourceInjectionServices.resolveResource(String jndiName, String mappedName)

An injection point should instead be registered properly using the following methods:

* ResourceInjectionServices.registerResourceInjectionPoint(InjectionPoint injectionPoint)

* ResourceInjectionServices.registerResourceInjectionPoint(String jndiName, String mappedName)

Web Service Injection Services

The resolution of @WebServiceRef (for injection into managed beans) is delegated to the container. An integrator must provide an implementation of JaxwsInjectionServices. This service is not required if the implementation of Injection Services takes care of @WebServiceRef injection.

Injection Services

An integrator may wish to use InjectionServices to provide additional field or method injection over-and-above that provided by Weld. An integration into a Java EE environment may use InjectionServices to provide EE resource injection for managed beans.

InjectionServices provides a very simple contract, the InjectionServices.aroundInject(InjectionContext ic); interceptor will be called for every instance that CDI injects, whether it is a contextual instance, or a non-contextual instance injected by InjectionTarget.inject().

The InjectionContext can be used to discover additional information about the injection being performed, including the target being injected. ic.proceed() should be called to perform CDI-style injection, and call initializer methods.

Resource injection point validation

For each

  • @Resource injection point

  • @PersistenceContext injection point

  • @PersistenceUnit injection point

  • @EJB injection point

  • @WebServiceRef injection point

Weld calls the InjectionServices.registerInjectionTarget() method. That allows the integrator to validate resource injection points before the application is deployed.

Security Services

In order to obtain the Principal representing the current caller identity, the container should provide an implementation of SecurityServices.

Initialization and shutdown

The org.jboss.weld.bootstrap.api.Bootstrap interface defines the initialization for Weld, bean deployment and bean validation. To boot Weld, you must create an instance of org.jboss.weld.bootstrap.WeldBootstrap which implements org.jboss.weld.bootstrap.api.CDI11Bootstrap which extends the above mentioned Bootstrap. Then you need to tell it about the services in use, and finally request the container start.

public interface Bootstrap {
    public Bootstrap startContainer(Environment environment, Deployment deployment);
    public Bootstrap startInitialization();
    public Bootstrap deployBeans();
    public Bootstrap validateBeans();
    public Bootstrap endInitialization();
    public void shutdown();
    public WeldManager getManager(BeanDeploymentArchive beanDeploymentArchive);
    public BeansXml parse(URL url);
    public BeansXml parse(Iterable<URL> urls);
    public BeansXml parse(Iterable<URL> urls, boolean removeDuplicates);
    public Iterable<Metadata<Extension>> loadExtensions(ClassLoader classLoader);
}

The bootstrap is split into phases, container initialization, bean deployment, bean validation and shutdown. Initialization will create a manager, and add the built-in contexts, and examine the deployment structure. Bean deployment will deploy any beans (defined using annotations, programmatically, or built in). Bean validation will validate all beans.

To initialize the container, you call Bootstrap.startInitialization(). Before calling startInitialization(), you must register any services required by the environment. You can do this by calling, for example, bootstrap.getManager().getServices().add(JpaServices.class, new MyJpaServices()).

Having called startInitialization(), the org.jboss.weld.manager.api.WeldManager for each BDA can be obtained by calling Bootstrap.getManager(BeanDeploymentArchive bda).

To deploy the discovered beans, call Bootstrap.deployBeans().

To validate the deployed beans, call Bootstrap.validateBeans().

To place the container into a state where it can service requests, call Bootstrap.endInitialization()

Note
Integrators can set org.jboss.weld.bootstrap.allowOptimizedCleanup configuration property using Defining external configuration to allow to perform efficient cleanup and further optimizations after bootstrap. In this case, Bootstrap.endInitialization() must be called after all EE components which support injection are installed (that means all relevant ProcessInjectionTarget events were already fired).

To shutdown the container you call Bootstrap.shutdown(). This allows the container to perform any cleanup operations needed.

Resource loading

Weld needs to load classes and resources from the classpath at various times. By default, they are loaded from the Thread Context ClassLoader if available, if not the same classloader that was used to load Weld, however this may not be correct for some environments. If this is case, you can implement org.jboss.weld.resources.spi.ResourceLoader.

import org.jboss.weld.bootstrap.api.Service;

public interface ResourceLoader extends Service {
    public Class<?> classForName(String name);
    public URL getResource(String name);
    public Collection<URL> getResources(String name);
}

ClassFileServices

Integrators with bytecode-scanning capabilities may implement an optional ClassFileServices service.

Bytecode-scanning is used by some application servers to speed up deployment. Compared to loading a class using ClassLoader, bytecode-scanning allows to obtain only a subset of the Java class file metadata (e.g. annotations, class hierarchy, etc.) which is usually loaded much faster. This allows the container to scan all classes initially by a bytecode scanner and then use this limited information to decide which classes need to be fully loaded using ClassLoader. Jandex is an example of a bytecode-scanning utility.

ClassFileServices may be used by an integrator to provide container’s bytecode-scanning capabilities to Weld. If present, Weld will try to use the service to avoid loading of classes that do not need to be loaded. These are classes that:

  • are not CDI managed beans and

  • are not assignable to any ProcessAnnotatedType observer

This usually yields improved bootstrap performance especially in large deployments with a lot of classes in explicit bean archives.

public interface ClassFileServices extends BootstrapService {
    ClassFileInfo getClassFileInfo(String className);
}
public interface ClassFileInfo {
    String getClassName();
    String getSuperclassName();
    boolean isAnnotationDeclared(Class<? extends Annotation> annotationType);
    boolean containsAnnotation(Class<? extends Annotation> annotationType);
    int getModifiers();
    boolean hasCdiConstructor();
    boolean isAssignableFrom(Class<?> javaClass);
    boolean isAssignableTo(Class<?> javaClass);
    boolean isVetoed();
    boolean isTopLevelClass();
    NestingType getNestingType();

See the JavaDoc for more details.

Registering services

The standard way for an integrator to provide Service implementations is via the deployment structure. Alternatively, services may be registered using the ServiceLoader mechanism. This is useful e.g. for a library running in weld-servlet environment. Such library may provide TransactionServices implementation which would not otherwise be provided by weld-servlet.

A service implementation should be listed in a file named META-INF/services/org.jboss.weld.bootstrap.api.Service

A service implementation can override another service implementation. The priority of a service implementation is determined from the javax.annotation.Priority annotation. Service implementations with higher priority have precedence. A service implementation that does not define priority explicitly is given implicit priority of 4500.

The contract with the container

There are a number of requirements that Weld places on the container for correct functioning that fall outside implementation of APIs.

Classloader isolation

If you are integrating Weld into an environment that supports deployment of multiple applications, you must enable, automatically, or through user configuration, classloader isolation for each CDI application.

Servlet

If you are integrating Weld into a Servlet environment you must register org.jboss.weld.servlet.WeldInitialListener and org.jboss.weld.servlet.WeldTerminalListener as Servlet listeners, either automatically, or through user configuration, for each CDI application which uses Servlet.

You must ensure that WeldInitialListener is called before any other application-defined listener is called and that WeldTerminalListener is called only after all application-defined listeners have been called.

You must ensure that WeldInitialListener.contextInitialized() is called after beans are deployed is complete (Bootstrap.deployBeans() has been called).

CDI Conversation Filter

A CDI implementation is required to provide a Servlet filter named ``CDI Conversation Filter''. The filter may be mapped by an application in the web descriptor. That allows application to place another filter around the CDI filter for dealing with exceptions.

Weld provides this filter with a fully qualified class name of`org.jboss.weld.servlet.ConversationFilter`.

If the application contains a filter mapping for a filter named CDI Conversation Filter'', the integrator is required to register org.jboss.weld.servlet.ConversationFilter as a filter with CDI Conversation Filter'' as its filter name. If no such mapping exists in the application, the integrator is not required to register the filter. In that case, WeldInitialListener will take care of conversation context activation/deactivation at the beginning of HTTP request processing.

JSF

If you are integrating Weld into a JSF environment you must register org.jboss.weld.el.WeldELContextListener as an EL Context listener.

If you are integrating Weld into a JSF environment you must register org.jboss.weld.jsf.ConversationAwareViewHandler as a delegating view handler.

If you are integrating Weld into a JSF environment you must obtain the bean manager for the module and then call BeanManager.wrapExpressionFactory(), passing Application.getExpressionFactory() as the argument. The wrapped expression factory must be used in all EL expression evaluations performed by JSF in this web application.

If you are integrating Weld into a JSF environment you must obtain the bean manager for the module and then call BeanManager.getELResolver(), The returned EL resolver should be registered with JSF for this web application.

Tip
There are a number of ways you can obtain the bean manager for the module. You could call Bootstrap.getManager(), passing in the BDA for this module. Alternatively, you could use the injection into Java EE component classes, or look up the bean manager in JNDI.

If you are integrating Weld into a JSF environment you must register org.jboss.weld.servlet.ConversationPropagationFilter as a Servlet listener, either automatically, or through user configuration, for each CDI application which uses JSF. This filter can be registered for all Servlet deployment safely.

Note
Weld 3 only supports JSF 2.2 and above.
Note
org.jboss.weld.servlet.ConversationPropagationFilter was deprecated and should no longer be used.

JSP

If you are integrating Weld into a JSP environment you must register org.jboss.weld.el.WeldELContextListener as an EL Context listener.

If you are integrating Weld into a JSP environment you must obtain the bean manager for the module and then call BeanManager.wrapExpressionFactory(), passing Application.getExpressionFactory() as the argument. The wrapped expression factory must be used in all EL expression evaluations performed by JSP.

If you are integrating Weld into a JSP environment you must obtain the bean manager for the module and then call BeanManager.getELResolver(), The returned EL resolver should be registered with JSP for this web application.

Tip
There are a number of ways you can obtain the bean manager for the module. You could call Bootstrap.getManager(), passing in the BDA for this module. Alternatively, you could use the injection into Java EE component classes, or look up the bean manager in JNDI.

Session Bean Interceptor

org.jboss.weld.ejb.SessionBeanInterceptor takes care of activating the request scope around EJB method invocations in a non-servlet environment, such as message-driven bean invocation, @Asynchronous invocation or @Timeout. If you are integrating Weld into an EJB environment you must register the aroundInvoke method of SessionBeanInterceptor as a EJB around-invoke interceptor for all EJBs in the application, either automatically, or through user configuration, for each CDI application which uses enterprise beans.

If you are running in a EJB 3.2 environment, you should register this as an around-timeout interceptor as well.

In addition, since CDI 1.1 the aroundInvoke method of SessionBeanInterceptor should be invoked around @PostConstruct callbacks of EJBs.

Important
You must register the SessionBeanInterceptor as the outer most interceptor in the stack for all EJBs.

The weld-core.jar

Weld can reside on an isolated classloader, or on a shared classloader. If you choose to use an isolated classloader, the default SingletonProvider, IsolatedStaticSingletonProvider, can be used. If you choose to use a shared classloader, then you will need to choose another strategy.

You can provide your own implementation of Singleton and SingletonProvider and register it for use using SingletonProvider.initialize(SingletonProvider provider).

Weld also provides an implementation of Thread Context Classloader per application strategy, via the TCCLSingletonProvider.

Binding the manager in JNDI

You should bind the bean manager for the bean deployment archive into JNDI at java:comp/BeanManager. The type should be javax.enterprise.inject.spi.BeanManager. To obtain the correct bean manager for the bean deployment archive, you may call bootstrap.getBeanManager(beanDeploymentArchive)

CDIProvider

CDI 1.1 provides a simplified approach to accessing the BeanManager / CDI container from components that do not support injection. This is done by the CDI class API. The integrating part can either use org.jboss.weld.AbstractCDI or org.jboss.weld.SimpleCDI provided by Weld core and register it using javax.enterprise.inject.spi.CDIProvider file that is visible to the CDI API classes or use the CDI.setCDIProvider(CDIProvider provider) method method early in the deployment.

Alternatively, an integrating part may provide a specialized implementation such as the one provided by WildFly integration.

Performing CDI injection on Java EE component classes

The CDI specification requires the container to provide injection into non-contextual resources for all Java EE component classes. Weld delegates this responsibility to the container. This can be achieved using the CDI defined InjectionTarget SPI. Furthermore, you must perform this operation on the correct bean manager for the bean deployment archive containing the EE component class.

The CDI specification also requires that a ProcessInjectionTarget event is fired for every Java EE component class. Furthermore, if an observer calls ProcessInjectionTarget.setInjectionTarget() the container must use the specified injection target to perform injection.

To help the integrator, Weld provides WeldManager.fireProcessInjectionTarget() which returns the InjectionTarget to use.

// Fire ProcessInjectionTarget, returning the InjectionTarget
// to use
AnnotatedType<?> at = weldBeanManager.createAnnotatedType(clazz);
InjectionTarget it = weldBeanManager.fireProcessInjectionTarget(at);

// Per instance required, create the creational context
CreationalContext<?> cc = beanManager.createCreationalContext(null);

// Produce the instance, performing any constructor injection required
Object instance = it.produce();

// Perform injection and call initializers
it.inject(instance, cc);

// Call the post-construct callback
it.postConstruct(instance);

// Call the pre-destroy callback
it.preDestroy(instance);

// Clean up the instance
it.dispose(instance);
cc.release();

The container may intersperse other operations between these calls. Further, the integrator may choose to implement any of these calls in another manner, assuming the contract is fulfilled.

When performing injections on EJBs you must use the Weld-defined SPI, WeldManager. Furthermore, you must perform this operation on the correct bean manager for the bean deployment archive containing the EJB.

// Obtain the EjbDescriptor for the EJB
// You may choose to use this utility method to get the descriptor
EjbDescriptor<T> ejbDescriptor = beanManager.<T>getEjbDescriptor(ejbName);

// Get the Bean object
Bean<T> bean = beanManager.getBean(ejbDescriptor);

// Create AnnotatedType from the implementation class of the EJB descriptor
AnnotatedType<T> at = beanManager.createAnnotatedType(descriptorImplClazz);

// Create the injection target
InjectionTarget<T> it = beanManager.createInjectionTarget(ejbDescriptor);

// Fire ProcessInjectionTarget event and store new IT as it can be modified by extensions
it = beanManager.fireProcessInjectionTarget(at, it);

// Per instance required, create the creational context
WeldCreationalContext<T> cc = beanManager.createCreationalContext(bean);

// register an AroundConstructCallback if needed
cc.setConstructorInterceptionSuppressed(true);
cc.registerAroundConstructCallback(new AroundConstructCallback<T>() {
    public T aroundConstruct(ConstructionHandle<T> handle, AnnotatedConstructor<T> constructor, Object[] parameters,
            Map<String, Object> data) throws Exception {
        // TODO: invoke @AroundConstruct interceptors
        return handle.proceed(parameters, data);
    }
});

// Produce the instance, performing any constructor injection required
T instance = it.produce(cc);

// Perform injection and call initializers
it.inject(instance, cc);

// You may choose to have CDI call the post construct and pre destroy
// lifecycle callbacks
// Call the post-construct callback
it.postConstruct(instance);

// Call the pre-destroy callback
it.preDestroy(instance);

// Clean up the instance
it.dispose(instance);
cc.release();

Around-construct interception

Weld implements support for constructor call interception and invokes interceptors that are associated with the particular component either using an interceptor binding or the @Interceptors annotation.

This can be suppressed by calling WeldCreationalContext.setConstructorInterceptionSuppressed(true)

In addition, an integrator may register a callback in which it performs additional operations around the constructor call. This way an integrator may for example implement support for additional interceptors (e.g. those bound using the deployment descriptor).

Probe Development Tool (Optional)

Optionally, an integrator may register the following Probe Development Tool components in order to enable its functionality. Note that these components should only be registered if the development mode is enabled - see also How to enable the development mode .

Table 16. Probe components
Class Type Description

org.jboss.weld.probe.ProbeFilter

Servlet filter

An integrator is required to register this filter for every web application which should be a subject of inspection. The filter should only be mapped to a single URL pattern of value /*.

org.jboss.weld.probe.ProbeExtension

CDI extension

An integrator is required to register this extension for every application which should be a subject of inspection.

Note
Probe classes reside in a separate module with the following coordinates: org.jboss.weld.probe:weld-probe-core. This module is a dependency of a Weld Servlet integration module and it’s also a part of the weld-servlet-shaded artifact and Weld OSGi bundle.
Note
Probe REST API is implemented using a servlet filter. However, not all servlet containers trigger filters when recieving a request to a path which is not mapped to any servlet (although most of them define a "default" servlet for each application). In this case, an integrator should register a "dummy" servlet (its methods will never be invoked) mapped to the URL pattern /weld-probe/*.

Optimized cleanup after bootstrap

Weld can perfom additional cleanup operations after bootstrap, in order to conserve resources. See for example Memory consumption optimization - removing unused beans .

However, this feature is disabled by default. An integrator may enable this feature provided the following requirements are met:

  • org.jboss.weld.bootstrap.api.Bootstrap#endInitialization() must be called after all EE components which support injection are installed (that means all relevant ProcessInjectionTarget events were already fired)

Table 17. Supported configuration properties
Configuration key Default value Description

org.jboss.weld.bootstrap.allowOptimizedCleanup

false

If set to true Weld is allowed to perform efficient cleanup and further optimizations after bootstrap

Note
This property can only be set by integrators through Defining external configuration .

Migration notes

This part of the appendix documents the changes in Weld across major and minor releases that an integrator should be aware of. These changes mostly touch changes in the SPI or in the container contract.

Migration from Weld 1.x to 2.0

All the changes are documented in this external migration document.

Migration from Weld 2.0 to 2.1

Logging

Weld no longer uses slf4j for logging. Instead, jboss-logging is now used as a logging facade.

HttpContextActivationFilter

A new service named HttpContextActivationFilter was added to the Weld SPI. This optional service allows an integrator to decide if CDI contexts should be activated or not for a given HTTP request. By default, CDI contexts are always active but this hook allows an integrator to eliminate the overhead of CDI context activation for certain types of requests where CDI is known not to be needed (e.g. request for a static resource).

Note that when the service is provided, user configuration is overriden.

Non-portable mode

The BootstrapConfiguration service now allows the non-portable mode to be enabled by the integrator.

Singleton SPI

Since Weld 2.1 the Singleton SPI requires the singleton to be identified by a String context id. This allows multiple Weld containers to run at the same time in environments where the TCCL cannot be used to distinguish the containers (e.g. OSGi environment).

The integrator should:

  • implement the new methods

  • use WeldBootstrap.startContainer(String contextId, Environment environment, Deployment deployment) to start Weld

  • eliminate all Container.instance() calls and replace them with Container.instance(String contextId)

Weld-OSGi bundle

The Weld-OSGi bundle does no include Weld’s runtime dependencies anymore. Therefore, it is possible to deploy the following artifacts in order to satisfy Weld’s dependencies:

group id artifact id version

org.jboss.logging

jboss-logging

3.1.3.GA

javax.enterprise

cdi-api

1.1-20130918

javax.annotation

javax.annotation-api

1.2

javax.interceptor

javax.interceptor-api

1.2

org.apache.geronimo.specs

geronimo-el_2.2_spec

1.0.3

Migration from Weld 2.1 to 2.2

Migration from Weld 2.2 to 2.3

  • The jboss-classfilewriter dependency, which is used by Weld for runtime bytecode generation, is no longer bundled within the Weld OSGi bundle. Instead, this dependency needs to be deployed separately to the OSGi container.

group id artifact id version

org.jboss.classfilewriter

jboss-classfilewriter

1.1.2.Final

  • EEModuleDescriptor which describes Java EE modules has been introduced and is now required as part of deployment structure metadata. See EE Modules for details.

  • Java 6 support was dropped. Java 7 or newer is now required for both compile time and runtime.

  • An observer for @Initialized(ConversationScoped.class) or @Destroyed(ConversationScoped.class) event no longer forces eager conversation context initialization. See also Lazy and eager conversation context initialization .

  • ScheduledExecutorServiceFactory is deprecated and no default implementation is provided by default. This service has not been used by Weld internals at least since version 1.1.0.Final.

Migration from Weld 2.3 to 2.4

  • Weld does not depend on com.google.guava:guava anymore. The dependency is also not bundled with shaded artifacts for Weld SE and Weld Servlet.

  • A wildcard type is not considered an unresolvable type variable - this reflects the output of a clarification issue CDI-494.

  • Deprecated org.jboss.weld.resources.SingleThreadScheduledExecutorServiceFactory was removed.

  • Weld SE:

    • org.jboss.weld.environment.se.contexts.activators.ActivateRequestScope was moved to the Weld API. From now on, the FQCN of the interceptor binding is: org.jboss.weld.context.activator.ActivateRequestScope.

    • Deprecated org.jboss.weld.environment.se.beans.InstanceManager was removed.

    • Deprecated org.jboss.weld.environment.se.ShutdownManager was removed.

    • Deprecated org.jboss.weld.environment.se.contexts.interceptors.ActivateThreadScope was removed.

Migration from Weld 2.4 to 3.0

Weld 3.0 implements CDI 2.0 so this is a huge update which contains bunch of new features. However, this document only covers part which might prove problematic while moving existing application from Weld 2.4 to Weld 3.0. For more information on the CDI 2.0 itself, please consult the specification.

Java 8

Both, Weld 3.0 and CDI 2.0 require Java 8 for compile time and runtime.

Shaded JARs name change

Weld 2.4 created shaded JARs for SE and Servlet with following artifact IDs: weld-se, weld-servlet. In Weld 3.0 a -shaded affix was added to the name of these artifacts to make it clear what they contain. E.g. new artifact IDs of these JARs are weld-se-shaded and weld-servlet-shaded respectively.

Weld 3 modules

Weld 3.0 was fine-grained and several optional modules were separated from the core. Namely, Weld now has Web, JTA, JSF and EJB modules.

The coordinates for these artifacts are as follows:

  • WEB - org.jboss.weld.module:weld-web

  • JTA - org.jboss.weld.module:weld-jta

  • JSF - org.jboss.weld.module:weld-jsf

  • EJB - org.jboss.weld.module:weld-ejb

Each module represents the logic behind Weld integration with the given technology.

beans.xml change for vetoed alternatives

Based on the decision taken in CDI-627, the behaviour of vetoed alternatives had changed slightly. beans.xml validation is now less strict and you can have a vetoed alternative while still having it enabled via beans.xml. This behaviour is the same as it was in CDI 1.0.

BeanManager#fireEvent was deprecated

While BeanManager#fireEvent still works, users are encouraged to use newly added BeanManager#getEvent method instead. This method returns an instance of Event<Object> built-in bean which can then have the types and qualifiers further specified via select method. It also allows to fire both kinds of events; synchronous and asynchronous. See the example below:

@Inject
BeanManager bm;

public void fireMyEvent() {
    bm.getEvent().select(Any.Literal.INSTANCE).fire(new Payload());
    bm.getEvent().select(PaymentCheck.class, Default.Literal.INSTANCE)
        .fireAsync(new Payload());
}
Weld-core artifact change

For historical reasons, Weld 2.4 core is released in two versions which are identical in their contents. Those are org.jboss.weld:weld-core and org.jboss.weld:weld-core-impl. Starting with Weld 3.0, only org.jboss.weld:weld-core-impl artifact will be released.

SPI changes

The SPI changes are mainly important for integrators, such as WildFly. Here is a list of changes based on what SPI class/method they affect:

  • org.jboss.weld.bootstrap.spi.BeanDeploymentArchive

    • Two new methods - getKnownClasses() and getLoadedBeanClasses(); both of them have default implementations

    • getLoadedBeanClasses()

      • Integrators might want to override this method if they want to make use of preloaded classes during bootstrap

    • getKnownClasses()

      • For explicit bean archive, the result of this method should be equal to that of getBeanClasses()

      • For implicit bean archive, it should also return types which have neither bean defining annotations nor session bean definitions

  • org.jboss.weld.bootstrap.spi.BeansXml

    • One new method - isTrimmed()

    • If an explicit bean archive contains the <trim/> element in its beans.xml file, types that don’t have either a bean defining annotation or any scope annotation, are removed from the set of discovered types.

    • If an integrator provides custom implementation of BeansXml interface, this method will need to be implemented as well

  • org.jboss.weld.security.spi.SecurityServices

    • One new method - getSecurityContext()

    • Returns current security context, which can then be propagated to different threads

    • This method has a default implementation which returns a no-op SecurityContext implementation

  • org.jboss.weld.security.spi.SecurityContext

    • Newly added interface which Weld uses to associate and dissociate security context with given thread

    • The main use case for this are asynchronous event observers which are executed in separate threads, yet need to have identical context

    • There are three methods in this interface - associate(), dissociate() and close()

  • org.jboss.weld.manager.api.ExecutorServices

    • One new method - getTimerExecutor()

    • Returns an instance of ScheduledExecutorService

    • This executor is only required for the timeout feature of asynchronous events

    • This method has a default implementation returning `null'

  • org.jboss.weld.manager.api.WeldManager

    • Following methods were removed from the SPI:

      • WeldManager.createActivity

      • WeldManager.getCurrent

      • WeldManager.setCurrentsetCurrent