Programming with JBoss Seam, using eclipse
Seam is an application framework for Java EE 5.
The best thing to start programming in seam is by going through the examples bundled with the seam distribution from http://labs.jboss.com/jbossseam/download/index.html, any thing else to start of will be second best for sure, I tried two books but non could give me a jump start like the start given by the seam examples.
Here I would also like to give you some comments about the two books I have gon through so that I could support you in making a choice of book for learning ahead after this post.
1) Apress.Beginning.JBoss.Seam.Feb.2007
Is a beginners book and assume that you have very little knowledge of EJBs and starts from scratch. the book clearly shows how easy and fast it is to program in JBoss Seam by comparing the way we program in struts with jboss for the same problem at hand.
2) Prentice.Hall.JBoss.Seam.Simplicity.and.Power.Beyond.Java.EE.Apr.2007
this book is not a beginners book but an intermediate one, the book is a comprehensive guide on Seam.
Let’s start Learning
Here we will cover one of the seam example application to understand how easy it is to develop application in JBoss Seam, various features of JBoss seam has been covered in my previous post titled “Features of JBoss Seam”.
Here we will also cover the way we can run the same examples using eclipse IDE and use the examples as template for our custom application development.
before starting with the example, lets have a quick look where seam sits in an enterprise application.
Seam does the role of a Context Management and JSF serving as a Request Controller, while in the presentation tier we have the option to use any of the three, JSP, Facelets and Portal and similarly for the State Management we can use EJB3, JBossjBPM or Hibernate.
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!
Before starting the example please follow the steps in my earlier post “Install and configure JBoss Seam” for performing the necessary setup for running JBoss Seam application.
“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.
Following is the registration screen of the application
Understanding the structure of application.
The application is implemented using two JSP pages, one entity bean and one stateless session bean.
Let’s take a look at the code, starting from the “bottom”.
The entity bean: User.java
This class serve two purposes
1) define persistence
2) and validation declaratively, via anotations
The code of this class is as follows, please find my comments with code as the explanation of the code with “->” mark
@Entity // -> indicates that the User class is an entity bean
@Name(“user”) // -> Seam components requre a component name provided by @Name anotations
@Scope(SESSION) // -> User bean is a session scope component.
@Table(name=”users”) // -> Persistence: User class is mapped to user table.
public class User implements Serializable {
private static final long serialVersionUID = 1881413500711441951L;
// -> name, password and username are the persistent attributes of the entity bean
private String username; (5)
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() {} (6)
// -> The @NotNull and @Lengthannotations are part of the Hibernate Validator framework
@NotNull @Length(min=5, max=15) (7)
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; }
// -> EJB standard @Id annotation indicates primary key attribute of entity bean.
@Id @NotNull @Length(min=5, max=15) (8)
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
}
Properties of our Userclass are bound to directly to JSF components and are populated by JSF during the update model values phase.
Now we will have a look at the state less session bean class RegisterAction.java which defines the action listner method.
RegisterAction.java
@Stateless // -> stateless session bean.@Name(“register”)public class RegisterAction implements Register{
@In // -> marks an attribute injected by Seam, In this case, the attribute is injected
// from a context variable named user private User user; @PersistenceContext // -> used to inject the EJB3 entity manager. private EntityManager em; @Logger // -> used to inject the component’s Log instance private Log log;public String register() (5)
{
List existing = em.createQuery(
“select username from User where username=#{user.username}”) (6)
.getResultList();
if (existing.size()==0)
{
em.persist(user);
log.info(“Registered new user #{user.username}”); (7)
return “/registered.jsp”; (8)
}
else
{
FacesMessages.instance().add(“User #{user.username} already exists”); (9)
return null;
}
}
}
Note that:
1) The LogAPI lets us easily display templated log messages.
2) JSF action listener methods return a string-valued outcome that determines what page will be displayed next. A null outcome (or a void action listener method) redisplays the previous page. In plain JSF, it is normal to always use a JSF navigation ruleto determine the JSF view id from the outcome. For complex application this indirection is useful and a good practice. However, for very simple examples like this one, Seam lets you use the JSF view id as the outcome, eliminating the requirement for a navigation rule. Note that when you use a view id as an outcome, Seam always performs a browser redirect.
3) Seam provides a number of built-in components to help solve common problems.
The FacesMessagescomponent makes it easy to display templated error or success messages. Built-in Seam components may be obtained by injection, or by calling an instance() method.
The session bean local interface:
Register.java
@Local public interface Register { public String register(); }
That’s the end of the Java code.
Now we will cover some of the deployment descriptors as most of the deployment files have common code among various applications.
1) components.xml
<components xmlns=”http://jboss.com/products/seam/components”
xmlns:core=”http://jboss.com/products/seam/core”>
<core:init jndi-pattern=”@jndiPattern@”/>
</components>
This code configures a property named jndiPattern of a built-in Seam component named org.jboss.seam.core.init.
2) web.xml
This web.xmlfile configures Seam and MyFaces
3) faces-config.xml
The faces-config.xmlfile integrates Seam into JSF
In fact, once you have all the basic descriptors set up, the onlyXML you need to write as you add new functionality to a Seam application is the navigation rules, and possibly jBPM process definitions. Seam takes the view that process flow and configuration data are the only things that truly belong in XML.
In this simple example, we don’t even need a navigation rule, since we decided to embed the view id in our action code.
4) ejb-jar.xml
The ejb-jar.xml file integrates Seam with EJB3, by attaching the SeamInterceptor to all session beans in the archive.
5) persistence.xml
The persistence.xmlfile tells the EJB persistence provider where to find the datasource
The view files
1) register.jsp
<%@ taglib uri=”http://java.sun.com/jsf/html” prefix=”h” %>
<%@ taglib uri=”http://java.sun.com/jsf/core” prefix=”f” %>
<%@ taglib uri=”http://jboss.com/products/seam/taglib” prefix=”s” %>
<html>
<head>
<title>Register New User</title>
</head>
<body>
<f:view>
<h:form>
<table border=”0″>
<s:validateAll>
<tr>
<td>Username</td>
<td><h:inputText value=”#{user.username}”/></td>
</tr>
<tr>
<td>Real Name</td>
<td><h:inputText value=”#{user.name}”/></td>
</tr>
<tr>
<td>Password</td>
<td><h:inputSecret value=”#{user.password}”/></td>
</tr>
</s:validateAll>
</table>
<h:messages/>
<h:commandButton type=”submit” value=”Register” action=”#{register.register}”/>
</h:form>
</f:view>
</body>
</html>
The only thing here that is specific to Seam is the <s:validateAll>tag. This JSF component tells JSF to validate all the contained input fields against the Hibernate Validator annotations specified on the entity bean.
2) registered.jsp
<%@ taglib uri=”http://java.sun.com/jsf/html” prefix=”h” %>
<%@ taglib uri=”http://java.sun.com/jsf/core” prefix=”f” %>
<html>
<head>
<title>Successfully Registered New User</title>
</head>
<body>
<f:view>
Welcome, <h:outputText value=”#{user.name}”/>,
you are successfully registered as <h:outputText value=”#{user.username}”/>.
</f:view>
</body>
</html>
How it works
When the form is submitted, JSF asks Seam to resolve the variable named user. Since there is no value already bound to that name (in any Seam context), Seam instantiates the user component, and returns the resulting Userentity bean instance to JSF after storing it in the Seam session context.
The form input values are now validated against the Hibernate Validator constraints specified on the Userentity. If the constraints are violated, JSF redisplays the page. Otherwise, JSF binds the form input values to properties of the User entity bean.
Next, JSF asks Seam to resolve the variable named register. Seam finds the RegisterActionstateless session bean in the stateless context and returns it. JSF invokes the register() action listener method.
Seam intercepts the method call and injects the User entity from the Seam session context, before continuing the invocation.
The register()method checks if a user with the entered username already exists. If so, an error message is queued with the FacesMessages component, and a null outcome is returned, causing a page redisplay. The FacesMessagescomponent interpolates the JSF expression embedded in the message string and adds a JSF FacesMessage to the view.
If no user with that username exists, the "/registered.jsp" outcome triggers a browser redirect to the registered.jsppage. When JSF comes to render the page, it asks Seam to resolve the variable named user and uses property values of the returned User entity from Seam’s session scope.
To run the example from eclipse
Step 1) In eclipse create a new java project with existing source code and give the name of the project as “registration”, browse to pint the directory where the “registration” example source code is unziped, then click on finish.
Step 2) add
testng.jar
myfaces-all.jar
jsf-api.jar
jboss-seam.jar
jboss-ejb3-all.jar
jboss-4.2.1.GA.jar
hibernate-all.jar
ejb3-persistence.jar
to your classpath.
Step 3) Right click build.xml of the registration project and select Run As – > Ant Build
Step 4) (make sure you have jboss server add before doing this step)
Select the “registration project” tree node from the navigator window to select “Debug As” -> “Open Debug Dialog” -> “Debug” to start the server in debug mode.
Step 5) open the browser window and type http://localhost:8080/seam-registration to start the “registration application”.




