Skip to main content

Trying out JBoss' Seam

Posted by bleonard on May 25, 2006 at 6:54 PM PDT

JBoss does a nice job of documenting their sample registration Seam application. To really help you learn the framework, including its benefits, I thought I walk you through the steps required to port a standard JSF / EJB 3.0 application to one that uses the Seam framework. To be consistent with JBoss' example, I've rewritten the registration application using standard JSF / EJB 3.0. Now let's port it back :-).

Getting Started
  • Download and install the NetBeans 5.5 Beta.
  • Download and install JBoss 4.0.4. During installation, be sure to select the ejb3 profile.
  • Download and extract JBoss Seam 1.0.0.CR3 (this is important, CR2 doesn't work with JBoss 4.0.4 GA)
  • Download and extract the Registration application.
Step 1: Add the JBoss Server to NetBeans
  1. Switch to the Runtime tab and right-click the Servers node to add a server.






  2. Select JBoss Application Server 4 from the Server drop down list. Change the name to JBoss Application Server 4.0.4.






  3. Complete the Add Server wizard.
  4. Stop the Sun Java System Application Server if it is running (both servers use http port 8080 as their default).
  5. Right-click the new JBoss server node and choose Start:





Step 2: Open the Registration Project

The Registration application is a NetBeans Enterprise Application Project, which is actually comprised of 3 projects: Registration, Registration-EJBModule and Registration-WebModule. Registraiton-EJBModule and Registration-WebModule are J2EE Modules of the Registration project. Registration-EJBModule generates the EJB jar file. Registration-WebModule generates the war file and Registration generates the ear file which contains the jar and war.

  1. Open the Registration project.
    The Enterprise Application Project stores the absolute location to its J2EE Modules. So, unless you extracted your project to the exact
    same location as me, you will see this dialog when you open the project.





  2. Click Close. The Registration project will be in bold red.
  3. Right click the project and select Resolve Reference Problems from the context menu.






  4. Use the Resolve Reference Problems dialog to map each module to its project, which you'll find are subdirectories beneath the Registration directory.



  5. After the references are resolved, right-click the Registration project and select Open Required Projects (now that the dependencies are correct, these dependent projects will always open for you).






  6. You'll notice the Registration-WebModule also has a reference problem, as it references the Registration-EJBModule. Use the same steps to correct the reference.
 
Step 3: Test Run the Registration Project

Remember, this is a standard JSF / EJB 3.0 project. Verify that it works before trying to use the Seam framework.

  1. Press F6 to run the project. This will build, package, deploy, start JBoss and launch the application in a browser for you.







    It's a simple application, but it will demonstrate a lot of the functionality provided by the Seam framework, such as:

    • Elimination of the Managed Bean - we will be able to completely eliminate our managed bean. Our web module will no longer contain any java files.
    • Validation - the 3 fields above are required. Also, Username and Password require and entry between 5 and 15 characters. We'll be able to specify these requirements in our entity class, rather then in our JSP.
    • Additional Seam Components - such as a convenience class for providing messaging back to the user.
 
Step 4: Add and Integrate the Seam Framework Into Your Project

In this step we're only going to integrate the required Seam components so that we can begin using the framework. We won't actually start using Seam until the next step. If NetBeans had direct support for the Seam framework, this is the stuff you'd expect the IDE to do for you.

Create the Seam Library

  1. Open the Library Manager (Tools menu) and create a new library called JBossSeam.
  2. Set the Classpath to jboss-seam.jar.
  3. Set the Sources to the JBoss Seam src directory.
  4. Set the Javadoc to the JBoss Seam doc directory.

This library is now available for use by any project.

Add the Seam Library to Your Project

  1. Right-click the Libraries node of the Registration-EJBModule project and choose Add Library.
  2. Add the JBossSeam library to the project.

Configure web.xml

  1. In the Registration-WebModule, open web.xml (under Configuration Files)
  2. Remove the javax.faces.CONFIG_FILES context parameter to work around a bug in MyFaces. You can read all the gory details here.
  3. Add the following Context Parameter:

         Param Name: org.jboss.seam.core.init.jndiPattern

         Param Value: registration/#{ejbName}/local



         



    Seam is going to bind your JSF action directly to a session bean, and it needs this pattern to do the JNDI lookup on your behalf. registration is the name of the ear file, so that would need to change accordingly for each application.


  4. Add the following Web Application Listener: org.jboss.seam.servlet.SeamListener.




Configure faces-config.xml

  1. Open faces-config.xml and add the following phase listener:



    <faces-config ...


        <lifecycle>
            <phase-listener>org.jboss.seam.jsf.SeamPhaseListener</phase-listener>         
        </lifecycle>
    </faces-config>



Add the Seam.properties file

It's interesting, the seam.properties file is empty, but Seam will not work without it.

  1. Press Ctrl+N to create a new file. Make sure Registration-EJBModule is selected as the project and select the Other Category > Properties File File Type.
  2. Name the file seam and put it in the src\conf Folder.

Unfortunately, the Seam framework expects to find this file in the root of the EJB jar file and not in the META-INF directory, so we have to create a custom Ant target to put it there.

  1. Switch to the Files tab and open Registration-EJBModule's build.xml.
  2. Add the following target:



    <target name="-pre-compile">
        <copy file="${meta.inf}/seam.properties" todir="${build.dir}/ear-module"/>
    </target>

Configure ejb-jar.xml

  1. Add the following assembly descriptor to ejb-jar.xml:



       <assembly-descriptor>
          <interceptor-binding>
             <ejb-name>*</ejb-name>
             <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
          </interceptor-binding>
       </assembly-descriptor>

    The SeamInterceptor integrates Seam with the Session Beans.

Test Your Changes

We haven't actually done anything with Seam, but we want to make sure our app still runs and we'll use the log to verify Sean was loaded successfully.

  1. Press F6 to run the project. The registration application should still run successfully and you should see an entry like the following in the JBoss log file.



    2006-05-24 19:13:27,968 INFO [javax.servlet.ServletContextListener] Welcome to Seam 1.0.0.CR3
 
Step 5: Eliminating Your Managed Bean



Mapping Directly to the Entity Class

In this section we're going to inject our JSF context variables directly into our entity class, which will allow us to eliminate the managed bean. If we look at our faces-config.xml, our managed bean is named "user" and has a "request" scope.

With Seam, we're going to provide this configuration information directly in our entity class, using annotations.

  1. Open User.java and add 2 new annotations: @Name("user") and @Scope(ScopeType.EVENT)







    The SeamListener will now map the JSF "user" context variable directly to our entity class, bypassing our managed bean, and set the scope of the context variable to request.

Mapping Directly to the Action Class

Currently, JSF calls our managed bean which in turn calls our action class. If we give our action class a name, we can bind to it directly from JSF, like we did above with the entity class.

  1. Open RegisterAction.java and add a Name annotation: @Name("register")





  2. Open register.jsp and change the action on the command button from user.register (the call to our managed bean) to register.register (the call directly to our action class).




Now, action methods in JSF cannot take any arguments, which was true of the register method in our managed bean, but not the case with the register method in our action class.

To get past this problem, we'll use another Seam feature, bijection (because it's bidirectional), to inject the User context object above into our action class.

  1. Add a user field to RegisterAction.java, annotated with @In, as follows:




  2. Then remove the arguments from the register method and pull the necessary values from the injected user field. Your updated method should look as follows:





    Also notice the convenience class FacesMessages that allows me to easily add a templated error message. This is one of the built-in Seam components that streamlines development.



  3. Don't forget to update the register method signature in the RegisterActionLocal interface.

Delete the Managed Bean

Are you ready?

  1. Delete the managed bean, BackingBean.java (yes, it's ok, you can do it).



  2. Delete the managed-bean entry from faces-config.xml. Otherwise, the faces servlet will fail trying to load the managed bean we just deleted.
Step 6: Test Our Seam Managed Application
  1. Press F6 to run the application. It should behave exactly as before, yet under the covers, it's now using Seam.



    Here's the completed application. You'll have to reslove the same reference problems as you did above.
Next Steps

I'd also like to use Seam to handle validation as well as page navigation. However, this blog entry has grown longer than I expected. Stay tuned for an additional entry covering these Seam features.

 

 

Related Topics >>