JBoss.orgCommunity Documentation

Chapter 12. Sample JSF-EJB3 Application

12.1. Data Model
12.2. JSF Web Pages
12.3. EJB3 Session Beans
12.4. Configuration and Packaging
12.4.1. Building The Application
12.4.2. Configuration Files
12.5. The Database
12.5.1. Creating the Database Schema
12.5.2. The HSQL Database Manager Tool
12.6. Deploying the Application

We use a simple "TODO" application to show how JSF and EJB3 work together in a web application. The "TODO" application works like this: You can create a new 'todo' task item using the "Create" web form. Each 'todo' item has a 'title' and a 'description'. When you submit the form, the application saves your task to a relational database. Using the application, you can view all 'todo' items, edit/delete an existing 'todo' item and update the task in the database.

The sample application comprises the following components:

Let's take a look at the contents of the Data Model represented by the Todo class in the Todo.java file. Each instance of the Todo class corresponds to a row in the relational database table. The 'Todo' class has three properties: id, title and description. Each of these correspond to a column in the database table.

The 'Entity class' to 'Database Table' mapping information is specified using EJB3 Annotations in the 'Todo' class. This eliminates the need for XML configuration and makes it a lot clearer. The @Entity annotation defines the Todo class as an Entity Bean. The @Id and @GeneratedValue annotations on the id property indicate that the id column is the primary key and that the server automatically generates its value for each Todo object saved into the database.

@Entity
public class Todo implements Serializable {

  private long id;
  private String title;
  private String description;

  public Todo () {
    title ="";
    description ="";
  }

  @Id @GeneratedValue
  public long getId() { return id;}
  public void setId(long id) { this.id = id; }

  public String getTitle() { return title; }
  public void setTitle(String title) {this.title = title;}

  public String getDescription() { return description; }
  public void setDescription(String description) {
    this.description = description;
  }

}

In this section we will show you how the web interface is defined using JSF pages. We will also see how the data model is mapped to the web form using JSF EL. Using the #{...} notation to reference Java objects is called JSF EL (JSF Expression Language). Lets take a look at the pages used in our application:

EJB 3.0 is one of the major improvements introduced with Java EE 5.0. It aims at reducing the complexity of older versions of EJB and simplifies Enterprise Java development and deployment. You will notice that to declare a class as a 'Session Bean' you simply have to annotate it. Using annotations eliminates the complexity involved with too many deployment descriptors. Also the only interface an EJB3 Session Bean requires is a business interface that declares all the business methods that must be implemented by the bean.

We will explore the two important source files associated with the Bean implementation in our application: TodoDaoInt.java and TodoDao.java.

We will build the sample application using Ant and explore the configuration and packaging details. Please install Ant if currently not installed on your computer.

Let's look at building the example application and then explore the configuration files in detail.

In Chapter 11, Sample Applications, we looked at the directory structure of the jsfejb3 sample application. At the command line, go to the jsfejb3 directory. There you will see a build.xml file. This is our Ant build script for compiling and packaging the archives. To build the application, you need to first of all edit the build.xml file and edit the value of jboss-dist to reflect the location where the JBoss Application Server is installed. Once you have done this, just type the command ant and your output should look like this:

[user@localhost jsfejb3]$ ant
Buildfile: build.xml

compile:
    [mkdir] Created dir: /jboss/gettingstarted/jsfejb3/build/classes
    [javac] Compiling 4 source files to /home/user/Desktop/gettingstarted/jsfejb3/build/classes
    [javac] Note: /jboss/gettingstarted/jsfejb3/src/TodoDao.java uses unchecked or unsafe operations.
    [javac] Note: Recompile with -Xlint:unchecked for details.

war:
    [mkdir] Created dir: /jboss/gettingstarted/jsfejb3/build/jars
      [war] Building war: /jboss/gettingstarted/jsfejb3/build/jars/app.war

ejb3jar:
      [jar] Building jar: /jboss/gettingstarted/jsfejb3/build/jars/app.jar

ear:
      [ear] Building ear: /jboss/gettingstarted/jsfejb3/build/jars/jsfejb3.ear

main:

BUILD SUCCESSFUL
Total time: 3 seconds

If you get the BUILD SUCCESSFUL message, you will find a newly created build directory with 2 sub-directories in it:

  • classes: containing the compiled class files.

  • jars: containing three archives - app.jar, app.war and jsfejb3.ear.

    • app.jar : EJB code and descriptors.

    • app.war : web application which provides the front end to allow users to interact with the business components (the EJBs). The web source (HTML, images etc.) contained in the jsfejb3/view directory is added unmodified to this archive. The Ant task also adds the WEB-INF directory that contains the files which aren’t meant to be directly accessed by a web browser but are still part of the web application. These include the deployment descriptors (web.xml) and extra jars required by the web application.

    • jsfejb3.ear : The EAR file is the complete application, containing the EJB modules and the web module. It also contains an additional descriptor, application.xml. It is also possible to deploy EJBs and web application modules individually but the EAR provides a convenient single unit.

Now that we have built the application, lets take a closer look at some of the important Configuration files. We have built the final archive ready for deployment - jsfejb3.ear. The contents of your EAR file should look like this:

jsfejb3.ear
|+ app.jar   // contains the EJB code
    |+ import.sql
    |+ Todo.class
    |+ TodoDao.class
    |+ TodoDaoInt.class
    |+ META-INF
        |+ persistence.xml
|+ app.war   // contains web UI
    |+ index.html
    |+ index.xhtml
    |+ create.xhtml
    |+ edit.xhtml
    |+ todos.xhtml
    |+ TodoBean.class
    |+ style.css
    |+ META-INF
    |+ WEB-INF
       |+ faces-config.xml
       |+ navigation.xml
       |+ web.xml
|+ META-INF  // contains the descriptors
    |+ application.xml
    |+ jboss-app.xml

Deploying an application in JBoss is simple and easy. You just have to copy the EAR file to the deploy directory in the 'server configuration' directory of your choice. Here, we will deploy it to the 'default' configuration, so we copy the EAR file to the JBOSS_DIST/jboss-as/server/default/deploy directory.

You should see something close to the following output from the server:

15:32:23,997 INFO  [EARDeployer] Init J2EE application: file:/jboss/jboss-as-5.0.0<release>/server/default/deploy/jsfejb3.ear
15:32:24,212 INFO  [JmxKernelAbstraction] creating wrapper delegate for: org.jboss.ejb3.
entity.PersistenceUnitDeployment
15:32:24,213 INFO  [JmxKernelAbstraction] installing MBean: persistence.units:ear=
jsfejb3.ear,jar=app.jar,unitName=helloworld with dependencies:
15:32:24,213 INFO  [JmxKernelAbstraction]       jboss.jca:name=DefaultDS,service=
DataSourceBinding
15:32:24,275 INFO  [PersistenceUnitDeployment] Starting persistence unit persistence.
units:ear=jsfejb3.ear,jar=app.jar,unitName=helloworld
15:32:24,392 INFO  [Ejb3Configuration] found EJB3 Entity bean: Todo
15:32:24,450 WARN  [Ejb3Configuration] Persistence provider caller does not implements 
the EJB3 spec correctly. PersistenceUnitInfo.getNewTempClassLoader() is null.
15:32:24,512 INFO  [Configuration] Reading mappings from resource : META-INF/orm.xml
15:32:24,512 INFO  [Ejb3Configuration] [PersistenceUnit: helloworld] no META-INF/orm.xml 
found
15:32:24,585 INFO  [AnnotationBinder] Binding entity from annotated class: Todo
15:32:24,586 INFO  [EntityBinder] Bind entity Todo on table Todo
.
.
.
.
15:32:26,311 INFO  [SchemaExport] Running hbm2ddl schema export
15:32:26,312 INFO  [SchemaExport] exporting generated schema to database
15:32:26,314 INFO  [SchemaExport] Executing import script: /import.sql
15:32:26,418 INFO  [SchemaExport] schema export complete
15:32:26,454 INFO  [NamingHelper] JNDI InitialContext properties:{java.naming.factory.
initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.
naming:org.jnp.interfaces}
15:32:26,484 INFO  [JmxKernelAbstraction] creating wrapper delegate for: org.jboss.ejb3.
stateless.StatelessContainer
15:32:26,485 INFO  [JmxKernelAbstraction] installing MBean: jboss.j2ee:ear=jsfejb3.ear,
jar=app.jar,name=TodoDao,service=EJB3 with dependencies:
15:32:26,513 INFO  [JmxKernelAbstraction]       persistence.units:ear=jsfejb3.ear,
jar=app.jar,unitName=helloworld
15:32:26,557 INFO  [EJBContainer] STARTED EJB: TodoDao ejbName: TodoDao
15:32:26,596 INFO  [EJB3Deployer] Deployed: file:/jboss/jboss-as-5.0.0<release>
server/default/tmp/deploy/
tmp33761jsfejb3.ear-contents/app.jar
15:32:26,625 INFO  [TomcatDeployer] deploy, ctxPath=/jsfejb3, warUrl=.../tmp/deploy/
tmp33761jsfejb3.ear-contents/app-exp.war/
15:32:26,914 INFO  [EARDeployer] Started J2EE application: file:/jboss/jboss-as-5.0.0<release>/server/default/deploy/jsfejb3.ear

If there are any errors or exceptions, make a note of the error message. Check that the EAR is complete and inspect the WAR file and the EJB jar files to make sure they contain all the necessary components (classes, descriptors etc.).

You can safely redeploy the application if it is already deployed. To undeploy it you just have to remove the archive from the deploy directory. There’s no need to restart the server in either case. If everything seems to have gone OK, then point your browser at the application URL.

http://localhost:8080/jsfejb3

You will be forwarded to the application main page. Figure 12.5, “Sample TODO” shows the sample application in action.