Get the app out

Discover the ins and outs of J2EE application assembly and deployment

We all built EJBs, servlets, and JSPs before J2EE came upon the scene at 1999's JavaOne. In those days, EJBs were deployed into EJB containers (mostly in application servers such as WebLogic or Netscape Application Server) using proprietary deployment descriptors. Servlets and JSPs, meanwhile, were deployed into servlet engines such as JRun, ServletExec, and JServ. In 1999, Sun altered the landscape by consolidating all the Java server-side technologies under a single banner called Java 2 Enterprise Edition -- J2EE.

This article shows programmers how to assemble and deploy J2EE applications based on EJBs, servlets, and JSP. We will begin with a brief introduction to the J2EE platform and J2EE applications, then dive straight into the mechanics of assembly and deployment.

The J2EE platform and J2EE applications

But why J2EE? The various specifications were doing just fine on their own, right? Individually that's true. For example, EJBs helped to separate and isolate the business logic portion of an application and to hide the unnecessary plumbing infrastructure. Servlets and JSPs both provided a means to create Web-based applications easily. Java Transaction Architecture (JTA) and Java Transaction Service (JTS) provided transactional capabilities to Java applications. JNDI helped applications find each other, while JDBC allowed connectability to relational databases. Individually, each technology performed its task satisfactorily, but the synergy created with their combination finally allows true Java-based enterprise applications. J2EE is the glue that ties them all together in a coherent bundle by defining how they work together to form a complete enterprise platform.

J2EE applications are applications written using the J2EE platform and deployed on a J2EE application server. They are composed of one or more J2EE components (classes developed based on the J2EE platform) and a J2EE application deployment descriptor. The deployment descriptor lists the application's components as modules. A J2EE module represents a J2EE application's basic unit of composition.

The J2EE component model also allows the various modules to be deployed as individual components, component libraries, or J2EE applications. J2EE modules include:

  • EJB JARs (EJBs)
  • Web application WARs (servlets, JSPs, and HTML files)
  • Application client JARs (typically, GUI programs running client-server, including applets)

That means that J2EE applications can not only be Web-based applications based on the J2EE platform, but also client-server applications, as long as they are based on the J2EE platform. Note that a J2EE application does not necessarily need to have EJBs -- it can contain just JSPs, servlets, and HTML files. It can also be simply a Java program (client-server) that accesses the J2EE platform, a gaggle of EJBs that work together, all three, or any two combinations.

This article describes packaging and deployment for EJBs and Web applications only. The deployment platform uses the Sun J2EE Reference Implementation (RI) Server version 1.2.1 running on Windows NT 4.0.

Assembly

As shown in Figure 1, the assembly of a J2EE application is hierarchical. First, the EJB classes are jarred up with a component deployment descriptor, then the Web resources such as the servlet, JSP, and HTML code are jarred up with their own component deployment descriptor. Those JAR and WAR files are then assembled and jarred into an Enterprise ARchive (EAR) file alongside an application deployment descriptor. Additional modules can be added as the application grows.

Figure 1. The structure of a J2EE application Click on thumbnail to view full-size image.

In the sections below, we'll examine the step-by-step process to create J2EE applications from EJB modules and Web applications.

EJBs

In J2EE, EJBs represent one of the three J2EE modules types included in a J2EE application. EJBs use the JAR format for packaging and delivery, so that all the necessary classes, interfaces, and other resources associated with the bean are included in one file. Be aware that if you are familiar with the EJB 1.0 packaging and deployment, you will notice that J2EE (which uses EJB 1.1) EJB packaging slightly differs. The packaging steps are:

  1. Create a deployment descriptor with the file named ejb-jar.xml, which you place in a directory named META-INF. Note that ejb-jar.xml must be at the top level of the META-INF directory of the EJB jar file. Moreover, it must be a valid XML document, according to the document type definition (DTD) for a J2EE:application XML document. The deployment descriptor must include an XML DTD with a PUBLIC identifier of:

    -//Sun Microsystems//   DTD Enterprise JavaBeans 1.1//EN
    

    Here's an example deployment descriptor:

    <?xml version="1.0" encoding="Cp1252"?>
    <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN' 'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>
    <ejb-jar>
      <description>My First J2ee Application EJBs</description>
      <display-name>AppJar</display-name>
      <enterprise-beans>
        <session>
          <description>Description of the EJBs here</description>
          <display-name> AppJar </display-name>
          <ejb-name> AppJar </ejb-name>
          <home>com.sttarfire.sample.ejb.AppHome</home>
          <remote> com.sttarfire.sample.ejb.App</remote>
          <ejb-class> com.sttarfire.sample.ejb.AppBean</ejb-class>
          <session-type>Stateless</session-type>
          <transaction-type>Bean</transaction-type>
        </session>
      </enterprise-beans>
    </ejb-jar>
    
  2. Place all EJB class files in their respective directories. For example, com.sttarfire.util.StringUtil.class should be in a subdirectory named com/sttarfire/util/.
  3. Supporting classes can be placed into the directories as well.
  4. If a library file is referred to, create a manifest.mf file and place it into the META-INF/ with the content pointing to the library file.
  5. Package all the files with the JAR file format. The file must be named with a .jar extension.

The resulting jar file is a J2EE module that is deployed standalone or included into the J2EE application EAR file. If you open it up using a file archive utility, it'll look something like:

/com/sttarfire/samples/ejb/App.class
/com/sttarfire/samples/ejb/AppHome.class
/com/sttarfire/samples/ejb/AppBean.class
/META-INF/ejb-jar.xml
/META-INF/manifest.mf

Web applications

As explained earlier, J2EE applications can consist of EJBs, Web applications, and/or Java clients. Web applications represent collections of servlets, JSPs, HTML pages, classes, and other resources that can be bundled and run on multiple containers from multiple vendors. Prior to J2EE, those individual components were deployed separately; in J2EE they all become neatly packaged into a Web ARchive (WAR) file for deployment as a Web application into a J2EE server. A deployed Web application is rooted at a specific path within a Web server.

A Web application may consist of the following items:

  • Servlets
  • JSPs
  • Utility classes
  • Static documents (HTML, images, sounds, etc.)
  • Client-side applets, beans, and classes
  • Descriptive meta information that ties all of the above elements together

A Web application needs to be archived into a single WAR file prior to inclusion into the overall EAR file. Note that individual WAR files can also be deployed separately into a J2EE server.

Creating a WAR file is similar to the creation of an EJB JAR file:

  1. First, create a deployment descriptor with the file named web.xml, which you'll place in a directory named WEB-INF. Again, note that web.xml must be at the top level of the WEB-INF directory of the war file. It must also be a valid XML document, according to the DTD for a J2EE:application XML document, just like the EJB deployment descriptor. The deployment descriptor must include an XML DTD with a PUBLIC identifier of:

    -//Sun Microsystems// DTD Web Application 2.2//EN
    

    Here's an example of a Web application deployment descriptor:

    <?xml version="1.0" encoding="Cp1252"?>
    <!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN' 'http://java.sun.com/j2ee/dtds/web-app_2.2.dtd'>
    <web-app>
      <display-name>AppWar</display-name>
      <description>My First J2EE Web Module</description>
      <servlet>
        <servlet-name>AppServlet</servlet-name>
        <display-name>AppServlet</display-name>
        <description>Description of the servlet here</description>
        <servlet-class>AppServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>AppServlet</servlet-name>
        <url-pattern>AppServlet</url-pattern>
      </servlet-mapping>
      <session-config>
        <session-timeout>0</session-timeout>
      </session-config>
    </web-app>
    
  2. Place all the servlet class files in the WEB-INF/classes/ directory.
  3. You can also place the supporting classes into the WEB-INF/lib/ directory.
  4. Package all the files using the JAR file format. The file must be named with a .war extension.

Like the EJB JAR, the Web application WAR file is a J2EE module that can be deployed standalone or included in the J2EE application EAR file. For programmers who have developed servlets and JSPs prior to J2EE, you will find this additional process to be very helpful during deployment. Indeed, you no longer need to figure out where to deploy the individual files; previously, you could place servlets, JSPs, HTML, and other resource files anywhere on a servlet engine (depending on the servlet engine in use). That situation could turn into a maintenance nightmare when different programmers placed servlets, JSPs, HTML, and other files in different places. Under the new model, deploying J2EE Web applications proves much simpler: Web applications are deployed to their respective context roots (described in the EAR deployment descriptor).

Note: the META-INF/ and WEB-INF/ directories are case-sensitive and should be entirely uppercase.

When you finish, the war file's structure should resemble:

/index.html
/howto.jsp
/feedback.jsp
/images/banner.gif
/images/somesample.gif
/WEB-INF/web.xml
/WEB-INF/lib/jspbean.jar
/WEB-INF/classes/com/sttarfire/servlets/AppServlet.class
/WEB-INF/classes/com/sttarfire/util/MyUtils.class

J2EE application

A J2EE application is a combination of one or more EJB JAR files, Web application WAR files, and application client JAR files (not discussed in detail here). As mentioned before, J2EE modules such as EJBs and the Web applications do not have to be packaged into a EAR file. Indeed, they can be deployed individually. But for a cleaner packaging of a single application, including all the necessary modules in a single file is much easier.

You package a J2EE application using the JAR file format into a file with an .ear extension. A minimal J2EE application package will contain only J2EE modules and the application deployment descriptor. Larger J2EE application packages may also include libraries referenced by J2EE modules, help files, and documentation to aid the deployer and other interested parties.

With that in mind, to create a EAR file, you will need to do the following:

  1. Create a deployment descriptor for the J2EE application, an XML file with the file name application.xml. Again, that file must be in a directory named META-INF and at the top level of the META-INF directory of the application EAR file. As before, it must be a valid XML document, according to the DTD for a J2EE:application XML document. The deployment descriptor must include an XML document type definition with a PUBLIC identifier of:

    -//Sun Microsystems//J2EE Application Deployment 1.0//EN
    

    An example of the J2EE application deployment descriptor is given below:

    <?xml version="1.0" encoding="Cp1252"?>
    <!DOCTYPE application PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE Application 1.2//EN' 'http://java.sun.com/j2ee/dtds/application_1_2.dtd'>
    <application>
      <display-name>MyJ2EEApp</display-name>
      <description>My First J2EE Application</description>
      <module>
        <ejb>AppJar.jar</ejb>
      </module>
      <module>
        <web>
          <web-uri>AppWeb.war</web-uri>
          <context-root>AppRoot</context-root>
        </web>
      </module>
    </application>
    
  2. Place the J2EE modules at the root directory level of the EAR file. As mentioned earlier, J2EE modules are EJB jar files, Web application WAR files, and standalone client jar files.
  3. Place any library files accessed from the various J2EE modules in the library/ directory.
  4. Place any server-specific deployment descriptors in whichever directory they need to go. For example, the Sun Reference Implementation of the J2EE Server has an additional deployment descriptor named sun-j2ee-ri.xml.
  5. Package all the files with the JAR file format. The file must be named with an .ear extension. That is the final archive file used for deployment in any J2EE-compliant server.

Here's what your EAR file might look like:

/AppJar.jar
/AppWar.war
/library/library.jar
/META-INF/application.xml
/META-INF/sun-j2ee-ri.xml
1 2 Page 1