# Weld 3.1.3.Final - CDI Reference Implementation

## CDI: Contexts and Dependency Injection for the Java EE platform

A note about naming and nomenclature
I. Beans
1. Introduction
1.1. What is a bean?
1.2. Getting our feet wet
2.1. The anatomy of a bean
2.1.1. Bean types, qualifiers and dependency injection
2.1.2. Scope
2.1.3. EL name
2.1.4. Alternatives
2.1.5. Interceptor binding types
2.2. What kinds of classes are beans?
2.2.1. Managed beans
2.2.2. Session beans
2.2.3. Producer methods
2.2.4. Producer fields
3. JSF web application example
4. Dependency injection and programmatic lookup
4.1. Injection points
4.2. What gets injected
4.3. Qualifier annotations
4.4. The built-in qualifiers @Default and @Any
4.5. Qualifiers with members
4.6. Multiple qualifiers
4.7. Alternatives
4.8. Fixing unsatisfied and ambiguous dependencies
4.9. Client proxies
4.10. Obtaining a contextual instance by programmatic lookup
4.10.1. Enhanced version of javax.enterprise.inject.Instance
4.11. The InjectionPoint object
5. Scopes and contexts
5.1. Scope types
5.2. Built-in scopes
5.3. The conversation scope
5.3.1. Conversation demarcation
5.3.2. Conversation propagation
5.3.3. Conversation timeout
5.3.4. CDI Conversation filter
5.3.5. Lazy and eager conversation context initialization
5.4. The singleton pseudo-scope
5.5. The dependent pseudo-scope
6. Getting started with Weld
6.1. Prerequisites
6.2. First try
6.3. Deploying to WildFly
6.4. Deploying to GlassFish
6.5. Deploying to Apache Tomcat
7. Diving into the Weld examples
7.1. The numberguess example in depth
7.1.1. The numberguess example in Apache Tomcat or Jetty
7.2. The numberguess example for Java SE with Swing
7.2.1. Creating the Eclipse project
7.2.2. Running the example from Eclipse
7.2.3. Running the example from the command line
7.2.4. Understanding the code
7.3. The translator example in depth
III. Loose coupling with strong typing
8. Producer methods
8.1. Scope of a producer method
8.2. Injection into producer methods
8.3. Disposer methods
9. Interceptors
9.1. Interceptor bindings
9.2. Implementing interceptors
9.3. Enabling interceptors
9.4. Interceptor bindings with members
9.5. Multiple interceptor binding annotations
9.6. Interceptor binding type inheritance
9.7. Use of @Interceptors
9.8. Enhanced version of javax.interceptor.InvocationContext
9.9. Loosening the limitations of InterceptionFactory
10. Decorators
10.1. Delegate object
10.2. Enabling decorators
11. Events
11.2. Event observers
11.3. Event producers
11.3.1. Synchronous event producers
11.3.2. Asynchronous event producers
11.3.3. Applying qualifiers to event
11.4. Conditional observer methods
11.5. Event qualifiers with members
11.6. Multiple event qualifiers
11.7. Transactional observers
11.8. Enhanced version of javax.enterprise.event.Event
12. Stereotypes
12.1. Default scope for a stereotype
12.2. Interceptor bindings for stereotypes
12.3. Name defaulting with stereotypes
12.4. Alternative stereotypes
12.5. Stereotype stacking
12.6. Built-in stereotypes
13. Specialization, inheritance and alternatives
13.1. Using alternative stereotypes
13.2. A minor problem with alternatives
13.3. Using specialization
14. Java EE component environment resources
14.1. Defining a resource
14.2. Typesafe resource injection
IV. CDI and the Java EE ecosystem
15. Java EE integration
15.1. Built-in beans
15.2. Injecting Java EE resources into a bean
15.3. Calling a bean from a servlet
15.4. Calling a bean from a message-driven bean
15.5. JMS endpoints
15.6. Packaging and deployment
15.6.1. Explicit bean archive
15.6.2. Implicit bean archive
15.6.3. Which archive is not a bean archive
15.6.4. Embeddable EJB container
16. Portable extensions
16.1. Creating an Extension
16.2. Container lifecycle events
16.2.1. Configurators
16.2.2. Weld-enriched container lifecycle events
16.3. The BeanManager object
16.4. The CDI class
16.5. The InjectionTarget interface
16.6. The Bean interface
16.7. Registering a Bean
16.8. Configuring an AnnotatedType
16.9. Overriding attributes of a bean
16.10. Wrapping an InjectionTarget
16.11. Overriding InjectionPoint
16.12. Manipulating interceptors, decorators and alternatives enabled for an application
16.13. The Context and AlterableContext interfaces
17. Next steps
V. Weld Reference Guide
18. Application servers and environments supported by Weld
18.1. Using Weld with WildFly
18.2. GlassFish
18.3. Servlet containers (such as Tomcat or Jetty)
18.3.1. Tomcat
18.3.2. Jetty
18.3.3. Undertow
18.3.4. WildFly Web
18.3.5. Bean Archive Isolation
18.3.6. Implicit Bean Archive Support
18.3.7. Servlet Container Detection
18.4. Java SE
18.4.1. CDI SE Module
18.4.2. Bootstrapping CDI SE
18.4.3. Request Context
18.4.5. Setting the Classpath
18.4.6. Bean Archive Isolation
18.4.7. Implicit Bean Archive Support
18.4.8. Extending Bean Defining Annotations
18.5. Weld SE and Weld Servlet cooperation
18.6. OSGi
19. Configuration
19.1. Weld configuration
19.1.1. Relaxed construction
19.1.2. Concurrent deployment configuration
19.1.4. Non-portable mode during application initialization
19.1.5. Proxying classes with final methods
19.1.6. Bounding the cache size for resolved injection points
19.1.7. Debugging generated bytecode
19.1.8. Injectable reference lookup optimization
19.1.9. Bean identifier index optimization
19.1.11. Development Mode
19.1.12. Conversation timeout and Conversation concurrent access timeout
19.1.13. Veto types without bean defining annotation
19.1.14. Memory consumption optimization - removing unused beans
19.2. Defining external configuration
19.3. Excluding classes from scanning and deployment
19.4. Mapping CDI contexts to HTTP requests
20. Logging
20.1. Java EE containers
20.2. Servlet containers
20.3. Weld SE
21. WeldManager interface
22. Development Mode
22.1. How to enable the development mode
22.1.1. Web application
22.1.2. Weld SE
22.1.3. Is The Development Mode Enabled?
22.2. Development Tools
22.2.1. Probe
22.2.2. Validation Report
23. Context Management
23.1. Managing the built in contexts
23.2. Propagating built-in contexts
23.2.1. New API methods supporting context propagation
23.2.2. Example of context propagation
23.2.3. Pitfalls and drawbacks
A. Integrating Weld into other environments
A.1. The Weld SPI
A.1.1. Deployment structure
A.1.2. EJB descriptors
A.1.3. EE resource injection and resolution services
A.1.4. EJB services
A.1.5. JPA services
A.1.6. Transaction Services
A.1.7. Resource Services
A.1.8. Web Service Injection Services
A.1.9. Injection Services
A.1.10. Security Services
A.1.11. Initialization and shutdown
A.1.13. ClassFileServices
A.1.14. Registering services
A.2. The contract with the container
A.2.2. Servlet
A.2.3. CDI Conversation Filter
A.2.4. JSF
A.2.5. JSP
A.2.6. Session Bean Interceptor
A.2.7. The weld-core.jar
A.2.8. Binding the manager in JNDI
A.2.9. CDIProvider
A.2.10. Performing CDI injection on Java EE component classes
A.2.11. Around-construct interception
A.2.12. Probe Development Tool (Optional)
A.2.13. Optimized cleanup after bootstrap
A.3. Migration notes
A.3.1. Migration from Weld 1.x to 2.0
A.3.2. Migration from Weld 2.0 to 2.1
A.3.3. Migration from Weld 2.1 to 2.2
A.3.4. Migration from Weld 2.2 to 2.3
A.3.5. Migration from Weld 2.3 to 2.4
A.3.6. Migration from Weld 2.4 to 3.0

# Part I. Beans

Weld, the CDI Reference Implementation (RI), can be downloaded from the download page. Information about the Weld source code repository and instructions about how to obtain and build the source can be found on the same page.

Weld provides a complete SPI allowing Java EE containers such as WildFly, GlassFish and WebLogic to use Weld as their built-in CDI implementation. Weld also runs in servlet engines like Tomcat and Jetty, or even in a plain Java SE environment.

Weld comes with an extensive library of examples, which are a great starting point from which to learn CDI. In addition, a number of quickstarts featuring CDI can be found at the JBoss Developer site

## Chapter 6. Getting started with Weld

Weld comes with a number of examples. We recommend you start with examples/jsf/numberguess and examples/jsf/translator. Numberguess is a web (war) example containing only non-transactional managed beans. This example can be run on a wide range of servers, including WildFly, GlassFish, Apache Tomcat, Jetty, and any compliant Java EE 8 container. Translator is an enterprise (ear) example that contains session beans. This example must be run on WildFly 14 or better, GlassFish 5.1 or better, or any compliant Java EE 8 container.

Both examples use JSF 2.3 as the web framework and, as such, can be found in the examples/jsf directory of the Weld distribution.

## 6.2. First try

If you simply want to run the numberguess example without the requirement of a specific runtime you can start with the following commands:

$> cd examples/jsf/numberguess$> mvn wildfly:run

The Maven WildFly plugin will run WildFly and deploy the example and the server will be automatically downloaded in the target directory. The numberguess application is available at http://localhost:8080/weld-numberguess.

## 6.3. Deploying to WildFly

To deploy the examples to a WildFly instance, you’ll need to download WildFly first. The good news is that there are no additional modifications you have to make to the server. It’s ready to go!

After you have downloaded WildFly, extract it. You can move the extracted folder anywhere you like. Wherever it lays to rest, that’s what we’ll call the WildFly installation directory, or JBOSS_HOME.

$> unzip wildfly-14.0.1.Final.zip$> mv wildfly-14.*/ wildfly-14

In order for the build scripts to know where to deploy the example, you have to tell them where to find your WildFly installation. Set the JBOSS_HOME environment variable to point to the WildFly installation, e.g.:

$> export JBOSS_HOME=/path/to/wildfly-14 You’re now ready to run your first example! Switch to the examples/jsf/numberguess directory and execute the Maven deploy target: $> cd examples/jsf/numberguess
$> mvn wildfly:deploy ## Note If you are using Eclipse, you should seriously consider installing the JBoss Tools add-ons, which include a wide variety of tooling for CDI and Java EE development, as well as an enhanced WildFly server view. Wait a few seconds for the application to deploy (or the application server to start) and see if you can determine the most efficient approach to pinpoint the random number at the local URL http://localhost:8080/weld-numberguess. ## Note The Maven WildFly plugin includes additional goals for WildFly to deploy and undeploy the archive. • mvn wildfly:deploy - deploy the example to a running WildFly instance • mvn wildfly:undeploy - undeploy the example from a running WildFly instance • mvn wildfly:redeploy - redeploys the example For more information on the WildFly Maven plugin see the plugin documentation. You can also run functional tests to verify that the example works as expected. Run: $> mvn verify -Darquillian=wildfly-managed

You should see the following output:

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

The second starter example, weld-translator, will translate your text into Latin. (Well, not really, but the stub is there for you to implement, at least. Good luck!) To try it out, switch to the translator example directory and execute the deploy target:

$> cd examples/jsf/translator/ear$> mvn wildfly:run

## Note

The translator uses session beans, which are packaged in an EJB module within an ear. Java EE 8 allows session beans to be deployed in war modules, but that’s a topic for a later chapter.

Again, wait a few seconds for the application to deploy (if you’re really bored, read the log messages), and visit http://localhost:8080/weld-translator to begin pseudo-translating.

Again, functional tests can be running by executing:

$> cd examples/jsf/translator/ftest$> mvn verify -Darquillian=wildfly-managed

## 6.5. Deploying to Apache Tomcat

Servlet containers are not required to support Java EE services like CDI. However, you can use CDI in a servlet container like Tomcat by embedding a standalone CDI implementation such as Weld.

Weld comes with servlet integration extension which bootstraps the CDI environment and provides injection into servlets components. Basically, it emulates some of the work done by the Java EE container, but you don’t get the enterprise features such as session beans and container-managed transactions.

Let’s give the Weld servlet extension a spin on Apache Tomcat. First, you’ll need to download Tomcat 9.0.11 or later from tomcat.apache.org and extract it.

$> unzip apache-tomcat-9.0.11.zip The Maven plugin communicates with Tomcat over HTTP, so it doesn’t care where you have installed Tomcat. However, the plugin configuration assumes you are running Tomcat in its default configuration, with a hostname of localhost and port 8080. The readme.txt file in the example directory has information about how to modify the Maven settings to accommodate a different setup. You can either start Tomcat from a Linux shell: $> cd /path/to/apache-tomcat-9
$> ./bin/startup.sh a Windows command window: $> cd c:\path\to\apache-tomcat-9\bin
$> start or you can start the server using an IDE, like Eclipse. Change to the examples/jsf/numberguess directory again and run the following Maven command: $> cd examples/jsf/numberguess
$> mvn clean package -Ptomcat Now you’re ready to deploy the numberguess example to Tomcat! $> cp examples/jsf/numberguess/target/weld-numberguess.war apache-tomcat/webapps/

## Chapter 7. Diving into the Weld examples

It’s time to pull the covers back and dive into the internals of Weld example applications. Let’s start with the simpler of the two examples, weld-numberguess.

## 7.2. The numberguess example for Java SE with Swing

This example shows how to use the Weld SE extension in a Java SE based Swing application with no EJB or servlet dependencies. This example can be found in the examples/se/numberguess folder of the Weld distribution.

### 7.2.1. Creating the Eclipse project

To use the Weld SE numberguess example in Eclipse, you can either import it as a Maven project if you have the m2eclipse plugin installed, or generate an Eclipse project and import it.

With m2eclipse installed, you can open any Maven project directly. From within Eclipse, select File -> Import…​ -> Existing Maven Projects. Then, browse to the location of the Weld SE numberguess example. You should see that Eclipse recognizes the Maven project.

Without m2eclipse plugin, you first have to generate an Eclipse project. Switch into the Weld SE numberguess example folder, then execute the Maven Eclipse plugin, as follows:

mvn eclipse:configure-workspace -Declipse.workspace=/path/to/your/eclipse/workspace

and then

mvn eclipse:eclipse

Then from within Eclipse, select File -> Import…​ -> Existing Projects into Workspace and browse to the location of the Weld SE numberguess example.

In both cases, you should now see a project in your workspace called weld-se-numberguess.

It’s time to get the example running!

### 7.2.4. Understanding the code

Let’s have a look at the significant code and configuration files that make up this example.

There is an empty beans.xml file in the root package (src/main/resources/META-INF/beans.xml), which marks this application as a CDI application.

The game’s main logic is located in Game.java. Here is the code for that class, highlighting the ways in which this differs from the web application version:

@ApplicationScoped
public class Game {
public static final int MAX_NUM_GUESSES = 10;

private Integer number;
private int guess = 0;
private int smallest = 0;

@Inject
@MaxNumber
private int maxNumber;

private int biggest;
private int remainingGuesses = MAX_NUM_GUESSES;
private boolean validNumberRange = true;

@Inject
Generator rndGenerator;

public Game() {
}

public int getNumber() {
return number;
}

public int getGuess() {
return guess;
}

public void setGuess(int guess) {
this.guess = guess;
}

public int getSmallest() {
return smallest;
}

public int getBiggest() {
return biggest;
}

public int getRemainingGuesses() {
return remainingGuesses;
}

public boolean isValidNumberRange() {
return validNumberRange;
}

public boolean isGameWon() {
return guess == number;
}

public boolean isGameLost() {
return guess != number && remainingGuesses <= 0;
}

public boolean check() {
boolean result = false;

if (checkNewNumberRangeIsValid()) {
if (guess > number) {
biggest = guess - 1;
}

if (guess < number) {
smallest = guess + 1;
}

if (guess == number) {
result = true;
}

remainingGuesses--;
}

return result;
}

private boolean checkNewNumberRangeIsValid() {
return validNumberRange = ((guess >= smallest) && (guess <= biggest));
}

@PostConstruct
public void reset() {
this.smallest = 0;
this.guess = 0;
this.remainingGuesses = 10;
this.biggest = maxNumber;
this.number = rndGenerator.next();
System.out.println("psst! the number is " + this.number);
}
}
 The bean is application scoped rather than session scoped, since an instance of a Swing application typically represents a single 'session'. Notice that the bean is not named, since it doesn’t need to be accessed via EL. In Java SE there is no JSF FacesContext to which messages can be added. Instead the Game class provides additional information about the state of the current game including: If the game has been won or lost If the most recent guess was invalid This allows the Swing UI to query the state of the game, which it does indirectly via a class called MessageGenerator, in order to determine the appropriate messages to display to the user during the game. Since there is no dedicated validation phase, validation of user input is performed during the check() method. The reset() method makes a call to the injected rndGenerator in order to get the random number at the start of each game. Note that it can’t use Instance.get() like the JSF example does because there will not be any active contexts like there are during a JSF request.

The MessageGenerator class depends on the current instance of Game and queries its state in order to determine the appropriate messages to provide as the prompt for the user’s next guess and the response to the previous guess. The code for MessageGenerator is as follows:

public class MessageGenerator {
@Inject
private Game game;

public String getChallengeMessage() {
StringBuilder challengeMsg = new StringBuilder("I'm thinking of a number between ");
challengeMsg.append(game.getSmallest());
challengeMsg.append(" and ");
challengeMsg.append(game.getBiggest());
challengeMsg.append(". Can you guess what it is?");

return challengeMsg.toString();
}

public String getResultMessage() {
if (game.isGameWon()) {
return "You guessed it! The number was " + game.getNumber();
} else if (game.isGameLost()) {
return "You are fail! The number was " + game.getNumber();
} else if (!game.isValidNumberRange()) {
return "Invalid number range!";
} else if (game.getRemainingGuesses() == Game.MAX_NUM_GUESSES) {
return "What is your first guess?";
} else {
String direction = null;

if (game.getGuess() < game.getNumber()) {
direction = "Higher";
} else {
direction = "Lower";
}

return direction + "! You have " + game.getRemainingGuesses() + " guesses left.";
}
}
}
 The instance of Game for the application is injected here. The Game’s state is interrogated to determine the appropriate challenge message …​ …​ and again to determine whether to congratulate, console or encourage the user to continue.

Finally we come to the NumberGuessFrame class which provides the Swing front end to our guessing game.

import javax.enterprise.event.Observes;

public class NumberGuessFrame extends javax.swing.JFrame {
@Inject
private Game game;

@Inject
private MessageGenerator msgGenerator;

public void start(@Observes ContainerInitialized event) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
initComponents();
setVisible(true);
}
});
}

private void initComponents() {

borderPanel = new javax.swing.JPanel();
gamePanel = new javax.swing.JPanel();
inputsPanel = new javax.swing.JPanel();
buttonPanel = new javax.swing.JPanel();
guessButton = new javax.swing.JButton();
...
mainLabel.setText(msgGenerator.getChallengeMessage());

messageLabel.setText(msgGenerator.getResultMessage());
...
}

private void guessButtonActionPerformed(java.awt.event.ActionEvent evt) {
int guess = -1;

try {
guess = Integer.parseInt(guessText.getText());
} catch (NumberFormatException nfe) {
// noop
}

game.setGuess(guess);
game.check();
refreshUI();

if (game.isGameWon() || game.isGameLost()) {
switchButtons();
}
}

private void replayBtnActionPerformed(java.awt.event.ActionEvent evt) {
game.reset();
refreshUI();
switchButtons();
}

private void switchButtons() {
CardLayout buttonLyt = (CardLayout) buttonPanel.getLayout();
buttonLyt.next(buttonPanel);
}

private void refreshUI() {
mainLabel.setText(msgGenerator.getChallengeMessage());
messageLabel.setText(msgGenerator.getResultMessage());
guessText.setText("");
guessesLeftBar.setValue(game.getRemainingGuesses());
guessText.requestFocus();
}

// swing components
private javax.swing.JPanel borderPanel;
...
private javax.swing.JButton replayBtn;

}
 The injected instance of the game (logic and state). The injected message generator for UI messages. This application is started in the prescribed Weld SE way, by observing the ContainerInitialized event. This method initializes all of the Swing components. Note the use of the msgGenerator here. guessButtonActionPerformed is called when the 'Guess' button is clicked, and it does the following: Gets the guess entered by the user and sets it as the current guess in the Game Calls game.check() to validate and perform one 'turn' of the game Calls refreshUI. If there were validation errors with the input, this will have been captured during game.check() and as such will be reflected in the messages returned by MessageGenerator and subsequently presented to the user. If there are no validation errors then the user will be told to guess again (higher or lower) or that the game has ended either in a win (correct guess) or a loss (ran out of guesses). Sets the button’s label based on the game state. replayBtnActionPerformed simply calls game.reset() to start a new game, refreshes the messages in the UI and sets the button’s label based on the game state.

## 7.3. The translator example in depth

The translator example will take any sentences you enter, and translate them to Latin. (Well, not really, but the stub is there for you to implement, at least. Good luck!)

The translator example is built as an EAR and contains EJBs. As a result, it’s structure is more complex than the numberguess example.

## Note

Java EE 7, which bundles EJB 3.2, allows you to package EJBs in a WAR, which will make this structure much simpler! Still, there are other advantages of using an EAR.

First, let’s take a look at the EAR aggregator project, which is located in the example’s ear directory. Maven automatically generates the application.xml for us from this plugin configuration:


<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
<modules>
<webModule>
<groupId>org.jboss.weld.examples.jsf.translator</groupId>
<artifactId>weld-jsf-translator-war</artifactId>
<contextRoot>/weld-translator</contextRoot>
</webModule>
</modules>
</configuration>
</plugin>


## Note

If you weren’t using Maven to generate these files, you would need META-INF/application.xml:


<application version="7"
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/application_7.xsd">

<display-name>weld-jsf-translator-ear</display-name>
<description>The Weld JSF translator example (ear)</description>

<module>
<web>
<web-uri>weld-translator.war</web-uri>
<context-root>/weld-translator</context-root>
</web>
</module>
<module>
<ejb>weld-translator.jar</ejb>
</module>
</application>


Next, let’s look at the WAR, which is located in the example’s war directory. Just as in the numberguess example, we have a faces-config.xml for JSF 2.2 and a web.xml (to activate JSF) under WEB-INF, both sourced from src/main/webapp/WEB-INF.

More interesting is the JSF view used to translate text. Just as in the numberguess example we have a template, which surrounds the form (omitted here for brevity):


<h:form id="TranslatorMain">

<table>
<tr align="center" style="font-weight: bold">
<td>
Your text
</td>
<td>
Translation
</td>
</tr>
<tr>
<td>
<h:inputTextarea id="text" value="#{translator.text}" required="true" rows="5" cols="80"/>
</td>
<td>
<h:outputText value="#{translator.translatedText}"/>
</td>
</tr>
</table>
<div>
<h:commandButton id="button" value="Translate" action="#{translator.translate}"/>
</div>

</h:form>


The user can enter some text in the left-hand text area, and hit the translate button to see the result to the right.

Finally, let’s look at the EJB module, which is located in the example’s ejb directory. In src/main/resources/META-INF there is just an empty beans.xml, used to mark the archive as containing beans.

## Note

The beans.xml file is no longer required for CDI enablement as of CDI 1.1. CDI is automatically enabled for archives which don’t contain beans.xml but contain one or more bean classes with a bean defining annotation, as described in section Section 15.6.2, “Implicit bean archive”.

We’ve saved the most interesting bit for last, the code! The project has two simple beans, SentenceParser and TextTranslator and two session beans, TranslatorControllerBean and SentenceTranslator. You should be getting quite familiar with what a bean looks like by now, so we’ll just highlight the most interesting bits here.

Both SentenceParser and TextTranslator are dependent beans, and TextTranslator uses constructor injection:

public class TextTranslator implements Serializable {

private SentenceParser sentenceParser;

@EJB private Translator translator;

@Inject public TextTranslator(SentenceParser sentenceParser) {
this.sentenceParser = sentenceParser;
}

public String translate(String text) {
StringBuilder sb = new StringBuilder();
for (String sentence: sentenceParser.parse(text)) {
sb.append(translator.translate(sentence)).append(". ");
}
return sb.toString().trim();
}

}

TextTranslator uses the simple bean (really just a plain Java class!) SentenceParser to parse the sentence and then calls on the stateless bean with the local business interface Translator to perform the translation. That’s where the magic happens. Of course, we couldn’t develop a full translator, but it’s convincing enough to anyone who doesn’t understand Latin!

@Stateless
public class SentenceTranslator implements Translator {

public String translate(String sentence) {
return "Lorem ipsum dolor sit amet";
}

}

Finally, there is UI orientated controller. This is a request scoped, named, stateful session bean, which injects the translator. It collects the text from the user and dispatches it to the translator. The bean also has getters and setters for all the fields on the page.

@Stateful
@RequestScoped
@Named("translator")
public class TranslatorControllerBean implements TranslatorController {

@Inject private TextTranslator translator;

private String inputText;

private String translatedText;

public void translate() {
translatedText = translator.translate(inputText);
}

public String getText() {
return inputText;
}

public void setText(String text) {
this.inputText = text;
}

public String getTranslatedText() {
return translatedText;
}

@Remove public void remove() {}

}

That concludes our short tour of the Weld starter examples. For more information on Weld, please visit http://weld.cdi-spec.org/.

# Part III. Loose coupling with strong typing

## Chapter 8. Producer methods

Producer methods let us overcome certain limitations that arise when a container, instead of the application, is responsible for instantiating objects. They’re also the easiest way to integrate objects which are not beans into the CDI environment.

According to the spec:

A producer method acts as a source of objects to be injected, where:

• the objects to be injected are not required to be instances of beans, or
• the concrete type of the objects to be injected may vary at runtime, or
• the objects require some custom initialization that is not performed by the bean constructor.

For example, producer methods let us:

• expose a JPA entity as a bean,
• expose any JDK class as a bean,
• define multiple beans, with different scopes or initialization, for the same implementation class, or
• vary the implementation of a bean type at runtime.

In particular, producer methods let us use runtime polymorphism with CDI. As we’ve seen, alternative beans are one solution to the problem of deployment-time polymorphism. But once the system is deployed, the CDI implementation is fixed. A producer method has no such limitation:

import javax.enterprise.inject.Produces;

@SessionScoped
public class Preferences implements Serializable {
private PaymentStrategyType paymentStrategy;
...
@Produces @Preferred
public PaymentStrategy getPaymentStrategy() {
switch (paymentStrategy) {
case CREDIT_CARD: return new CreditCardPaymentStrategy();
case CHECK: return new CheckPaymentStrategy();
case PAYPAL: return new PayPalPaymentStrategy();
default: return null;
}
}
}

Consider an injection point:

@Inject @Preferred PaymentStrategy paymentStrategy;

This injection point has the same type and qualifier annotations as the producer method, so it resolves to the producer method using the usual CDI injection rules. The producer method will be called by the container to obtain an instance to service this injection point.

## Chapter 10. Decorators

Interceptors are a powerful way to capture and separate concerns which are orthogonal to the application (and type system). Any interceptor is able to intercept invocations of any Java type. This makes them perfect for solving technical concerns such as transaction management, security and call logging. However, by nature, interceptors are unaware of the actual semantics of the events they intercept. Thus, interceptors aren’t an appropriate tool for separating business-related concerns.

The reverse is true of decorators. A decorator intercepts invocations only for a certain Java interface, and is therefore aware of all the semantics attached to that interface. Since decorators directly implement operations with business semantics, it makes them the perfect tool for modeling some kinds of business concerns. It also means that a decorator doesn’t have the generality of an interceptor. Decorators aren’t able to solve technical concerns that cut across many disparate types. Interceptors and decorators, though similar in many ways, are complementary. Let’s look at some cases where decorators fit the bill.

Suppose we have an interface that represents accounts:

public interface Account {
public BigDecimal getBalance();
public User getOwner();
public void withdraw(BigDecimal amount);
public void deposit(BigDecimal amount);
}

Several different beans in our system implement the Account interface. However, we have a common legal requirement that; for any kind of account, large transactions must be recorded by the system in a special log. This is a perfect job for a decorator.

A decorator is a bean (possibly even an abstract class) that implements the type it decorates and is annotated @Decorator.

@Decorator
public abstract class LargeTransactionDecorator
implements Account {
...
}

The decorator implements the methods of the decorated type that it wants to intercept.

@Decorator
public abstract class LargeTransactionDecorator
implements Account {
@Inject @Delegate @Any Account account;

@PersistenceContext EntityManager em;

public void withdraw(BigDecimal amount) {
...
}

public void deposit(BigDecimal amount);
...
}
}

Unlike other beans, a decorator may be an abstract class. Therefore, if there’s nothing special the decorator needs to do for a particular method of the decorated interface, you don’t need to implement that method.

Interceptors for a method are called before decorators that apply to the method.

## Chapter 12. Stereotypes

The CDI specification defines a stereotype as follows:

In many systems, use of architectural patterns produces a set of recurring bean roles. A stereotype allows a framework developer to identify such a role and declare some common metadata for beans with that role in a central place.

A stereotype encapsulates any combination of:

• a default scope, and
• a set of interceptor bindings.

A stereotype may also specify that:

• all beans with the stereotype have defaulted bean names, or that
• all beans with the stereotype are alternatives.

A bean may declare zero, one or multiple stereotypes. Stereotype annotations may be applied to a bean class or producer method or field.

A stereotype is an annotation, annotated @Stereotype, that packages several other annotations. For instance, the following stereotype identifies action classes in some MVC framework:

@Stereotype
@Retention(RUNTIME)
@Target(TYPE)
...
public @interface Action {}

We use the stereotype by applying the annotation to a bean.

@Action
public class LoginAction { ... }

Of course, we need to apply some other annotations to our stereotype or else it wouldn’t be adding much value.

## Chapter 13. Specialization, inheritance and alternatives

When you first start developing with CDI, you’ll likely be dealing only with a single bean implementation for each bean type. In this case, it’s easy to understand how beans get selected for injection. As the complexity of your application grows, multiple occurrences of the same bean type start appearing, either because you have multiple implementations or two beans share a common (Java) inheritance. That’s when you have to begin studying the specialization, inheritance and alternative rules to work through unsatisfied or ambiguous dependencies or to avoid certain beans from being called.

The CDI specification recognizes two distinct scenarios in which one bean extends another:

• The second bean specializes the first bean in certain deployment scenarios. In these deployments, the second bean completely replaces the first, fulfilling the same role in the system.
• The second bean is simply reusing the Java implementation, and otherwise bears no relation to the first bean. The first bean may not even have been designed for use as a contextual object.

The second case is the default assumed by CDI. It’s possible to have two beans in the system with the same part bean type (interface or parent class). As you’ve learned, you select between the two implementations using qualifiers.

The first case is the exception, and also requires more care. In any given deployment, only one bean can fulfill a given role at a time. That means one bean needs to be enabled and the other disabled. There are a two modifiers involved: @Alternative and @Specializes. We’ll start by looking at alternatives and then show the guarantees that specialization adds.

## Chapter 14. Java EE component environment resources

Java EE 5 already introduced some limited support for dependency injection, in the form of component environment injection. A component environment resource is a Java EE component, for example a JDBC datasource, JMS queue or topic, JPA persistence context, remote EJB or web service.

Naturally, there is now a slight mismatch with the new style of dependency injection in CDI. Most notably, component environment injection relies on string-based names to qualify ambiguous types, and there is no real consistency as to the nature of the names (sometimes a JNDI name, sometimes a persistence unit name, sometimes an EJB link, sometimes a non-portable "mapped name"). Producer fields turned out to be an elegant adaptor to reduce all this complexity to a common model and get component environment resources to participate in the CDI system just like any other kind of bean.

Fields have a duality in that they can both be the target of Java EE component environment injection and be declared as a CDI producer field. Therefore, they can define a mapping from a string-based name in the component environment, to a combination of type and qualifiers used in the world of typesafe injection. We call a producer field that represents a reference to an object in the Java EE component environment a resource.

# Part V. Weld Reference Guide

## 18.3. 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.3.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>
<version>3.1.3.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>


### 18.3.1. Tomcat

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

#### 18.3.1.2. 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.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);
}
}
}
 Weld’s org.jboss.weld.environment.servlet.Listener registered programmatically

### 18.3.2. 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.

#### 18.3.2.2. 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

<?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.

#### 18.3.2.5. 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);

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);
}
}
}
 Jetty’s org.eclipse.jetty.webapp.DecoratingListener registered programmatically (since Jetty-9.4.20) Weld’s org.jboss.weld.environment.servlet.Listener registered programmatically

### 18.3.3. 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()
.setContextPath("/")
.setDeploymentName("test.war")

manager.deploy();

HttpHandler servletHandler = manager.start();
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);
}
}
}
 Weld’s org.jboss.weld.environment.servlet.Listener registered programmatically:

### 18.3.6. Implicit Bean Archive Support

CDI 1.1 introduced the bean discovery mode of annotated used for implicit bean archives (see also Section 15.6, “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.

## 19.2. 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.PROXY_DUMP.get(), "/home/weld");
return properties;
}
}

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 Section 19.1, “Weld configuration”. Also note that entries with unsupported properties will be ignored while invalid property values will lead to deployment problem.

## 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 Section 15.6, “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.**">
</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.