Seam Reference Guide

JBoss Enterprise Application Platform

Written By: Gavin King, Christian Bauer, Norman Richards, Shane Bryzak, Pete Muir, Emmanuel Bernard, Max Andersen, Michael Youngstrom, Thomas Heute, Michael Yuan

Japanese Translation: Fusayuki Minamoto, Takayoshi Kimura, Takayoshi Osawa, Reiko Ohtsuka, Syunpei Shiraishi, Toshiya Kobayashi, Shigeaki Wakizaka, Ken Yamada, Noriko Mizumoto

Copyright © 2008 Red Hat, Inc. This material may only be distributed subject to the terms and conditions set forth in the Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License (which is presently available at http://creativecommons.org/licenses/by-nc-sa/3.0/).

Red Hat and the Red Hat "Shadow Man" logo are registered trademarks of Red Hat, Inc. in the United States and other countries.

All other trademarks referenced herein are the property of their respective owners.

The GPG fingerprint of the security@redhat.com key is:

CA 20 86 86 2B D6 9D FC 65 F6 EC C4 21 91 80 CD DB 42 A6 0E

1801 Varsity Drive
RaleighNC 27606-2072
USA
Phone: +1 919 754 3700
Phone: 888 733 4281
Fax: +1 919 754 3701
PO Box 13588
Research Triangle ParkNC 27709
USA

Sep, 2007

Abstract

This book is a Reference Guide to Seam 1.2 for JBoss Enterprise Application Platform 4.3.


1. Feedback
Introduction to JBoss Seam
2. Seam Tutorial
2.1. Try the examples
2.1.1. Running the examples on JBoss AS
2.1.2. Running the examples on Tomcat
2.1.3. Running the example tests
2.2. Your first Seam application: the registration example
2.2.1. Understanding the code
2.2.2. How it works
2.3. Clickable lists in Seam: the messages example
2.3.1. Understanding the code
2.3.2. How it works
2.4. Seam and jBPM: the todo list example
2.4.1. Understanding the code
2.4.2. How it works
2.5. Seam pageflow: the numberguess example
2.5.1. Understanding the code
2.5.2. How it works
2.6. A complete Seam application: the Hotel Booking example
2.6.1. Introduction
2.6.2. Overview of the booking example
2.6.3. Understanding Seam conversations
2.6.4. The Seam UI control library
2.6.5. The Seam Debug Page
2.7. A complete application featuring Seam and jBPM: the DVD Store example
2.8. A complete application featuring Seam workspace management: the Issue Tracker example
2.9. An example of Seam with Hibernate: the Hibernate Booking example
2.10. A RESTful Seam application: the Blog example
2.10.1. Using "pull"-style MVC
2.10.2. Bookmarkable search results page
2.10.3. Using "push"-style MVC in a RESTful application
3. The contextual component model
3.1. Seam contexts
3.1.1. Stateless context
3.1.2. Event context
3.1.3. Page context
3.1.4. Conversation context
3.1.5. Session context
3.1.6. Business process context
3.1.7. Application context
3.1.8. Context variables
3.1.9. Context search priority
3.1.10. Concurrency model
3.2. Seam components
3.2.1. Stateless session beans
3.2.2. Stateful session beans
3.2.3. Entity beans
3.2.4. JavaBeans
3.2.5. Message-driven beans
3.2.6. Interception
3.2.7. Component names
3.2.8. Defining the component scope
3.2.9. Components with multiple roles
3.2.10. Built-in components
3.3. Bijection
3.4. Lifecycle methods
3.5. Conditional installation
3.6. Logging
3.7. The Mutable interface and @ReadOnly
3.8. Factory and manager components
4. Configuring Seam components
4.1. Configuring components via property settings
4.2. Configuring components via components.xml
4.3. Fine-grained configuration files
4.4. Configurable property types
4.5. Using XML Namespaces
5. Events, interceptors and exception handling
5.1. Seam events
5.1.1. Page actions
5.1.2. Component-driven events
5.1.3. Contextual events
5.2. Seam interceptors
5.3. Managing exceptions
5.3.1. Exceptions and transactions
5.3.2. Enabling Seam exception handling
5.3.3. Using annotations for exception handling
5.3.4. Using XML for exception handling
6. Conversations and workspace management
6.1. Seam's conversation model
6.2. Nested conversations
6.3. Starting conversations with GET requests
6.4. Using <s:link> and <s:button>
6.5. Success messages
6.6. Using an "explicit" conversation id
6.7. Workspace management
6.7.1. Workspace management and JSF navigation
6.7.2. Workspace management and jPDL pageflow
6.7.3. The conversation switcher
6.7.4. The conversation list
6.7.5. Breadcrumbs
6.8. Conversational components and JSF component bindings
7. Pageflows and business processes
7.1. Pageflow in Seam
7.1.1. The two navigation models
7.1.2. Seam and the back button
7.2. Using jPDL pageflows
7.2.1. Installing pageflows
7.2.2. Starting pageflows
7.2.3. Page nodes and transitions
7.2.4. Controlling the flow
7.2.5. Ending the flow
7.3. Business process management in Seam
7.4. Using jPDL business process definitions
7.4.1. Installing process definitions
7.4.2. Initializing actor ids
7.4.3. Initiating a business process
7.4.4. Task assignment
7.4.5. Task lists
7.4.6. Performing a task
8. Seam and Object/Relational Mapping
8.1. Introduction
8.2. Seam managed transactions
8.2.1. Enabling Seam-managed transactions
8.3. Seam-managed persistence contexts
8.3.1. Using a Seam-managed persistence context with JPA
8.3.2. Using a Seam-managed Hibernate session
8.3.3. Seam-managed persistence contexts and atomic conversations
8.4. Using the JPA "delegate"
8.5. Using EL in EJB-QL/HQL
8.6. Using Hibernate filters
9. JSF form validation in Seam
10. The Seam Application Framework
10.1. Introduction
10.2. Home objects
10.3. Query objects
10.4. Controller objects
11. Seam and JBoss Rules
11.1. Installing rules
11.2. Using rules from a Seam component
11.3. Using rules from a jBPM process definition
12. Security
12.1. Overview
12.1.1. Which mode is right for my application?
12.2. Requirements
12.3. Authentication
12.3.1. Configuration
12.3.2. Writing an authentication method
12.3.3. Writing a login form
12.3.4. Simplified Configuration - Summary
12.3.5. Handling Security Exceptions
12.3.6. Login Redirection
12.3.7. Advanced Authentication Features
12.4. Error Messages
12.5. Authorization
12.5.1. Core concepts
12.5.2. Securing components
12.5.3. Security in the user interface
12.5.4. Securing pages
12.5.5. Securing Entities
12.6. Writing Security Rules
12.6.1. Permissions Overview
12.6.2. Configuring a rules file
12.6.3. Creating a security rules file
12.7. SSL Security
12.8. Implementing a Captcha Test
12.8.1. Configuring the Captcha Servlet
12.8.2. Adding a Captcha to a page
13. Internationalization and themes
13.1. Locales
13.2. Labels
13.2.1. Defining labels
13.2.2. Displaying labels
13.2.3. Faces messages
13.3. Timezones
13.4. Themes
13.5. Persisting locale and theme preferences via cookies
14. Seam Text
14.1. Basic fomatting
14.2. Entering code and text with special characters
14.3. Links
14.4. Entering HTML
15. iText PDF generation
15.1. Using PDF Support
15.2. Creating a document
15.2.1. p:document
15.3. Basic Text Elements
15.3.1. p:paragraph
15.3.2. p:text
15.3.3. p:font
15.3.4. p:newPage
15.3.5. p:image
15.3.6. p:anchor
15.4. Headers and Footers
15.4.1. p:header and p:footer
15.4.2. p:pageNumber
15.5. Chapters and Sections
15.5.1. p:chapter and p:section
15.5.2. p:title
15.6. Lists
15.6.1. p:list
15.6.2. p:listItem
15.7. Tables
15.7.1. p:table
15.7.2. p:cell
15.8. Document Constants
15.8.1. Color Values
15.8.2. Alignment Values
15.9. Configuring iText
15.10. iText links
16. Email
16.1. Creating a message
16.1.1. Attachments
16.1.2. HTML/Text alternative part
16.1.3. Multiple recipients
16.1.4. Multiple messages
16.1.5. Templating
16.1.6. Internationalisation
16.1.7. Other Headers
16.2. Receiving emails
16.3. Configuration
16.3.1. mailSession
16.4. Tags
17. Asynchronicity and messaging
17.1. Asynchronicity
17.1.1. Asynchronous methods
17.1.2. Asynchronous events
17.2. Messaging in Seam
17.2.1. Configuration
17.2.2. Sending messages
17.2.3. Receiving messages using a message-driven bean
17.2.4. Receiving messages in the client
18. Caching
18.1. Using JBossCache in Seam
18.2. Page fragment caching
19. Remoting
19.1. Configuration
19.2. The "Seam" object
19.2.1. A Hello World example
19.2.2. Seam.Component
19.2.3. Seam.Remoting
19.3. Client Interfaces
19.4. The Context
19.4.1. Setting and reading the Conversation ID
19.5. Batch Requests
19.6. Working with Data types
19.6.1. Primitives / Basic Types
19.6.2. JavaBeans
19.6.3. Dates and Times
19.6.4. Enums
19.6.5. Collections
19.7. Debugging
19.8. The Loading Message
19.8.1. Changing the message
19.8.2. Hiding the loading message
19.8.3. A Custom Loading Indicator
19.9. Controlling what data is returned
19.9.1. Constraining normal fields
19.9.2. Constraining Maps and Collections
19.9.3. Constraining objects of a specific type
19.9.4. Combining Constraints
19.10. JMS Messaging
19.10.1. Configuration
19.10.2. Subscribing to a JMS Topic
19.10.3. Unsubscribing from a Topic
19.10.4. Tuning the Polling Process
20. Spring Framework integration
20.1. Injecting Seam components into Spring beans
20.2. Injecting Spring beans into Seam components
20.3. Making a Spring bean into a Seam component
20.4. Seam-scoped Spring beans
20.5. Spring Application Context as a Seam Component
21. Configuring Seam and packaging Seam applications
21.1. Basic Seam configuration
21.1.1. Integrating Seam with JSF and your servlet container
21.1.2. Seam Resource Servlet
21.1.3. Seam servlet filters
21.1.4. Integrating Seam with your EJB container
21.1.5. Using facelets
21.1.6. Don't forget!
21.2. Configuring Seam in Java EE 5
21.2.1. Packaging
21.3. Configuring Seam in Java SE, with the JBoss Embeddable EJB3 container
21.3.1. Installing the Embeddable EJB3 container
21.3.2. Configuring a datasource with the Embeddable EJB3 container
21.3.3. Packaging
21.4. Configuring Seam in J2EE
21.4.1. Boostrapping Hibernate in Seam
21.4.2. Boostrapping JPA in Seam
21.4.3. Packaging
21.5. Configuring Seam in Java SE, with the JBoss Microcontainer
21.5.1. Using Hibernate and the JBoss Microcontainer
21.5.2. Packaging
21.6. Configuring jBPM in Seam
21.6.1. Packaging
21.7. Configuring Seam in a Portal
21.8. Configuring SFSB and Session Timeouts in JBoss AS
22. Seam annotations
22.1. Annotations for component definition
22.2. Annotations for bijection
22.3. Annotations for component lifecycle methods
22.4. Annotations for context demarcation
22.5. Annotations for transaction demarcation
22.6. Annotations for exceptions
22.7. Annotations for validation
22.8. Annotations for Seam Remoting
22.9. Annotations for Seam interceptors
22.10. Annotations for asynchronicity
22.11. Annotations for use with JSF dataTable
22.12. Meta-annotations for databinding
22.13. Annotations for packaging
23. Built-in Seam components
23.1. Context injection components
23.2. Utility components
23.3. Components for internationalization and themes
23.4. Components for controlling conversations
23.5. jBPM-related components
23.6. Security-related components
23.7. JMS-related components
23.8. Mail-related components
23.9. Infrastructural components
23.10. Special components
24. Seam JSF controls
25. Expression language enhancements
25.1. Configuration
25.2. Usage
25.3. Limitations
25.3.1. Incompatibility with JSP 2.1
25.3.2. Calling a MethodExpression from Java code
26. Testing Seam applications
26.1. Unit testing Seam components
26.2. Integration testing Seam applications
26.2.1. Using mocks in integration tests
27. Seam tools
27.1. jBPM designer and viewer
27.1.1. Business process designer
27.1.2. Pageflow viewer
27.2. CRUD-application generator
27.2.1. Creating a Hibernate configuration file
27.2.2. Creating a Hibernate Console configuration
27.2.3. Reverse engineering and code generation
Index

Chapter 1. Feedback

If you spot a typo in this guide, or if you have thought of a way to make this manual better, we would love to hear from you! Submit a report in JIRA against the Product: JBoss Enterprise Application Platform, Version: <version>, Component: Doc. If you have a suggestion for improving the documentation, try to be as specific as possible. If you have found an error, include the section number and some of the surrounding text so we can find it easily.

Introduction to JBoss Seam

Seam is an application framework for Java EE 5. It is inspired by the following principles:

Integrate JSF with EJB 3.0

JSF and EJB 3.0 are two of the best new features of Java EE 5. EJB3 is a brand new component model for server side business and persistence logic. Meanwhile, JSF is a great component model for the presentation tier. Unfortunately, neither component model is able to solve all problems in computing by itself. Indeed, JSF and EJB3 work best used together. But the Java EE 5 specification provides no standard way to integrate the two component models. Fortunately, the creators of both models foresaw this situation and provided standard extension points to allow extension and integration of other solutions.

Seam unifies the component models of JSF and EJB3, eliminating glue code, and letting the developer think about the business problem.

Integrated AJAX

Seam supports two open source JSF-based AJAX solutions: ICEfaces and Ajax4JSF. These solutions let you add AJAX capability to your user interface without the need to write any JavaScript code.

Seam also provides a built-in JavaScript remoting layer for EJB3 components. AJAX clients can easily call server-side components and subscribe to JMS topics, without the need for an intermediate action layer.

Neither of these approaches would work well, were it not for Seam's built-in concurrency and state management, which ensures that many concurrent fine-grained, asynchronous AJAX requests are handled safely and efficiently on the server side.

Integrate Business Process as a First Class Construct

Optionally, Seam integrates transparent business process management via jBPM. You won't believe how easy it is to implement complex workflows using jBPM and Seam.

Seam even allows definition of presentation tier conversation flow by the same means.

JSF provides an incredibly rich event model for the presentation tier. Seam enhances this model by exposing jBPM's business process related events via exactly the same event handling mechanism, providing a uniform event model for Seam's uniform component model.

One Kind of "Stuff"

Seam provides a uniform component model. A Seam component may be stateful, with the state associated to any one of a number of contexts, ranging from the long-running business process to a single web request.

There is no distinction between presentation tier components and business logic components in Seam. It is possible to write Seam applications where "everything" is an EJB. This may come as a surprise if you are used to thinking of EJBs as coarse-grained, heavyweight objects that are a pain in the backside to create! However, EJB 3.0 completely changes the nature of EJB from the point of view of the developer. An EJB is a fine-grained object - nothing more complex than an annotated JavaBean. Seam even encourages you to use session beans as JSF action listeners!

Unlike plain Java EE or J2EE components, Seam components may simultaneously access state associated with the web request and state held in transactional resources (without the need to propagate web request state manually via method parameters). You might object that the application layering imposed upon you by the old J2EE platform was a Good Thing. Well, nothing stops you creating an equivalent layered architecture using Seam - the difference is that you get to architect your own application and decide what the layers are and how they work together.

Declarative State Management

We are all used to the concept of declarative transaction management and J2EE declarative security from EJB 2.x. EJB 3.0 even introduces declarative persistence context management. These are three examples of a broader problem of managing state that is associated with a particular context, while ensuring that all needed cleanup occurs when the context ends. Seam takes the concept of declarative state management much further and applies it to application state. Traditionally, J2EE applications almost always implement state management manually, by getting and setting servlet session and request attributes. This approach to state management is the source of many bugs and memory leaks when applications fail to clean up session attributes, or when session data associated with different workflows collides in a multi-window application. Seam has the potential to almost entirely eliminate this class of bugs.

Declarative application state management is made possible by the richness of the context model defined by Seam. Seam extends the context model defined by the servlet spec—request, session, application—with two new contexts—conversation and business process—that are more meaningful from the point of view of the business logic.

Bijection

The notion of Inversion of Control or dependency injection exists in both JSF and EJB3, as well as in numerous so-called "lighweight containers". Most of these containers emphasize injection of components that implement stateless services. Even when injection of stateful components is supported (such as in JSF), it is virtually useless for handling application state because the scope of the stateful component cannot be defined with sufficient flexibility.

Bijection differs from IoC in that it is dynamic, contextual, and bidirectional. You can think of it as a mechanism for aliasing contextual variables (names in the various contexts bound to the current thread) to attributes of the component. Bijection allows auto-assembly of stateful components by the container. It even allows a component to safely and easily manipulate the value of a context variable, just by assigning to an attribute of the component.

Workspace Management

Optionally, Seam applications may take advantage of workspace management, allowing users to freely switch between different conversations (workspaces) in a single browser window. Seam provides not only correct multi-window operation, but also multi-window-like operation in a single window!

Annotated POJOs Everywhere

EJB 3.0 embraces annotations and "configuration by exception" as the easiest way to provide information to the container in a declarative form. Unfortunately, JSF is still heavily dependent on verbose XML configuration files. Seam extends the annotations provided by EJB 3.0 with a set of annotations for declarative state management and declarative context demarcation. This lets you eliminate the noisy JSF managed bean declarations and reduce the required XML to just that information which truly belongs in XML (the JSF navigation rules).

Testability as a Core Feature

Seam components, being POJOs, are by nature unit testable. But for complex applications, unit testing alone is insufficient. Integration testing has traditionally been a messy and difficult task for Java web applications. Therefore, Seam provides for testability of Seam applications as a core feature of the framework. You can easily write JUnit or TestNG tests that reproduce a whole interaction with a user, exercising all components of the system apart from the view (the JSP or Facelets page). You can run these tests directly inside your IDE, where Seam will automatically deploy EJB components into the JBoss Embeddable EJB3 container.

Get started now!

Seam works in any application server that supports EJB 3.0. You can even use Seam in a servlet container like Tomcat, or in any J2EE application server, by leveraging the new JBoss Embeddable EJB3 container.

However, we realize that not everyone is ready to make the switch to EJB 3.0. So, in the interim, you can use Seam as a framework for applications that use JSF for presentation, Hibernate (or plain JDBC) for persistence and JavaBeans for application logic. Then, when you're ready to make the switch to EJB 3.0, migration will be straightforward.

It turns out that the combination of Seam, JSF and EJB3 is the simplest way to write a complex web application in Java. You won't believe how little code is required!

Chapter 2. Seam Tutorial

2.1. Try the examples

In this tutorial, we'll assume that you are using JBoss AS 4.2 with Seam, as in the case of JBoss Enterprise Application Platform.

The directory structure of each example in Seam follows this pattern:

  • Web pages, images and stylesheets may be found in examples/registration/view

  • Resources such as deployment descriptors and data import scripts may be found in examples/registration/resources

  • Java source code may be found in examples/registration/src

  • The Ant build script is examples/registration/build.xml

2.1.1. Running the examples on JBoss AS

First, make sure you have Ant correctly installed, with $ANT_HOME and $JAVA_HOME set correctly. Next, make sure you set the location of your JBoss AS installation in the build.properties file in the root folder of your Seam installation. If you haven't already done so, start JBoss AS now by typing bin/run.sh or bin/run.bat in the root directory of your JBoss installation.

By default the examples will deploy to the default configuration of the server. These examples should be deployed to the production configuration if they are to be used with JBoss Enterprise Application Platform 4.2, and the example build.xml file should be modified to reflect this before building and deploying. Two lines should be changed in this file:

 <property name="deploy.dir"           value="${jboss.home}/server/production/deploy"/>
   <property name="webroot.dir"         
	value="${deploy.dir}/jboss-web.deployer/ROOT.war"/>

Now, build and deploy the example by typing ant deploy in the examples/registration directory.

Try it out by accessing http://localhost:8080/seam-registration/ with your web browser.

2.1.2. Running the examples on Tomcat

First, make sure you have Ant correctly installed, with $ANT_HOME and $JAVA_HOME set correctly. Next, make sure you set the location of your Tomcat installation in the build.properties file in the root folder of your Seam installation.

Now, build and deploy the example by typing ant deploy.tomcat in the examples/registration directory.

Finally, start Tomcat.

Try it out by accessing http://localhost:8080/jboss-seam-registration/ with your web browser.

When you deploy the example to Tomcat, any EJB3 components will run inside the JBoss Embeddable EJB3 container, a complete standalone EJB3 container environment.

2.1.3. Running the example tests

Most of the examples come with a suite of TestNG integration tests. The easiest way to run the tests is to run ant testexample inside the examples/registration directory. It is also possible to run the tests inside your IDE using the TestNG plugin.

2.2. Your first Seam application: the registration example

The registration example is a fairly trivial application that lets a new user store his username, real name and password in the database. The example isn't intended to show off all of the cool functionality of Seam. However, it demonstrates the use of an EJB3 session bean as a JSF action listener, and basic configuration of Seam.

We'll go slowly, since we realize you might not yet be familiar with EJB 3.0.

The start page displays a very basic form with three input fields. Try filling them in and then submitting the form. This will save a user object in the database.

2.2.1. Understanding the code

The example is implemented with two JSP pages, one entity bean and one stateless session bean.

Let's take a look at the code, starting from the "bottom".

2.2.1.1. The entity bean: User.java

We need an EJB entity bean for user data. This class defines persistence and validation declaratively, via annotations. It also needs some extra annotations that define the class as a Seam component.

@Entity
@Name("user")
@Scope(SESSION)
@Table(name="users")
public class User implements Serializable
{
   private static final long serialVersionUID = 1881413500711441951L;
   
   private String username;
   private String password;
   private String name;
   
   public User(String name, String password, String username)
   {
      this.name = name;
      this.password = password;
      this.username = username;
   }
   
   public User() {}
   
   @NotNull @Length(min=5, max=15)
   public String getPassword()
   {
      return password;
   }

   public void setPassword(String password)
   {
      this.password = password;
   }
   
   @NotNull
   public String getName()
   {
      return name;
   }

   public void setName(String name)
   {
      this.name = name;
   }
   
   @Id @NotNull @Length(min=5, max=15)
   public String getUsername()
   {
      return username;
   }

   public void setUsername(String username)
   {
      this.username = username;
   }

}
1

The EJB3 standard @Entity annotation indicates that the User class is an entity bean.

2

A Seam component needs a component name specified by the @Name annotation. This name must be unique within the Seam application. When JSF asks Seam to resolve a context variable with a name that is the same as a Seam component name, and the context variable is currently undefined (null), Seam will instantiate that component, and bind the new instance to the context variable. In this case, Seam will instantiate a User the first time JSF encounters a variable named user.

3

Whenever Seam instantiates a component, it binds the new instance to a context variable in the component's default context. The default context is specified using the @Scope annotation. The User bean is a session scoped component.

4

The EJB standard @Table annotation indicates that the User class is mapped to the users table.

5

name, password and username are the persistent attributes of the entity bean. All of our persistent attributes define accessor methods. These are needed when this component is used by JSF in the render response and update model values phases.

6

An empty constructor is both required by both the EJB specification and by Seam.

7

The @NotNull and @Length annotations are part of the Hibernate Validator framework. Seam integrates Hibernate Validator and lets you use it for data validation (even if you are not using Hibernate for persistence).

8

The EJB standard @Id annotation indicates the primary key attribute of the entity bean.

The most important things to notice in this example are the @Name and @Scope annotations. These annotations establish that this class is a Seam component.

We'll see below that the properties of our User class are bound to directly to JSF components and are populated by JSF during the update model values phase. We don't need any tedious glue code to copy data back and forth between the JSP pages and the entity bean domain model.

However, entity beans shouldn't do transaction management or database access. So we can't use this component as a JSF action listener. For that we need a session bean.

Example 2.1. 

2.2.1.2. The stateless session bean class: RegisterAction.java

Most Seam application use session beans as JSF action listeners (you can use JavaBeans instead if you like).

We have exactly one JSF action in our application, and one session bean method attached to it. In this case, we'll use a stateless session bean, since all the state associated with our action is held by the User bean.

This is the only really interesting code in the example!

@Stateless
@Name("register")
public class RegisterAction implements Register
{

   @In
   private User user;
   
   @PersistenceContext
   private EntityManager em;
   
   @Logger
   private Log log;
   
   public String register()
   {
      List existing = em.createQuery(
         "select username from User where username=#{user.username}")
         .getResultList();
         
      if (existing.size()==0)
      {
         em.persist(user);
         log.info("Registered new user #{user.username}");
         return "/registered.jsp";
      }
      else
      {
         FacesMessages.instance().add("User #{user.username} already exists");
         return null;
      }
   }

}
1

The EJB standard @Stateless annotation marks this class as stateless session bean.

2

The @In annotation marks an attribute of the bean as injected by Seam. In this case, the attribute is injected from a context variable named user (the instance variable name).

3

The EJB standard @PersistenceContext annotation is used to inject the EJB3 entity manager.

4