Section 3.3. Common JAR


3.3. Common JAR

In the previous chapter, we created a CarBean POJO to hold the various attributes of a car. We stored it in the WAR file because, well, you didn't have any other choice at that time. We should now reconsider the storage location for the CarBean to maximize its reuse.

By the end of this book, we will pull cars out of a database in the persistence tier, and hand them to objects in the business tier, which ultimately will pass them up to the presentation tier. An object that is shared across tiers is a perfect candidate for the Common JAR .

In addition to custom domain objects, the Common JAR is a great location to store common libraries such as Log4J or JDOM. While both WARs and EJB JARs have lib directories, they are best used for tier-specific libraries. For example, the JSTL JARs belong in the WARthey have no other purpose than to support the creation of web pages. On the other hand, logging is something that happens throughout the codebaseit really belongs in a common JAR.

Let's factor our CarBean out of the WAR and into the Common JAR. In addition to moving directories, we're going to rename it to better describe its purpose in the application.

The suffix "Bean" is a bit overloaded: it includes JavaBeans, Enterprise Java Beans, Session Beans, Message-Driven Beans, JMX MBeans, and the list goes on. The design pattern that best describes the CarBean's function is a Data Transfer Object (DTO), so when we move the bean, we'll also rename it CarDTO. The source code will remain the same, but the name will give us a better idea about the true purpose of the class.

3.3.1. Exploring the New Directory Structure

The previous chapter included only the webapp directory. If you change to the ch03/03a-ear directory, you'll see that we've expanded to a webapp directory and a common directory.

We also expanded from one to three build.xml files. Each subdirectory has its own build.xml, and the master build file lives in the top-level directory. The goal is to keep each portion of the application as autonomous as possible. Granted, most of the application will depend on the common sub-project , but by providing individual Ant scripts you have the opportunity to build each portion of the project separately.

3.3.1.1. The common sub-project

Take a moment to explore the common sub-project. It contains a single classCarDTO. We have created a new package structure to store all DTOscom.jbossatwork.dto.

You can build this sub-project by typing ant in the common directory. It compiles the CarDTO class and bundles it up into a JAR file. After you've built the sub-project, change to the build/distribution directory and type jar tvf common.jar to verify that the CarDTO class is indeed stored in common.jar.

3.3.1.2. The webapp sub-project

The only change to the webapp sub-project from the previous chapter is the removal of the CarDTO class. To accommodate this change, we now must import the com.jbossatwork.dto package at the top of ControllerServlet.

We also have to change our build.xml script to include the common.jar in our classpath. Notice that the definition of common.jar.dir uses a relative path to step up one level from the basedir of the webapp sub-project and down into the common sub-project's output directory in Example 3-2.

Example 3-2. webapp build.xml
 <property name="lib.dir" value="lib"/> <property name="compile.lib.dir" value="compile-lib"/> <property name="common.jar.dir" value="../common/build/distribution"/> <path >     <fileset dir="${compile.lib.dir}">         <include name="**/*.jar"/>     </fileset>     <fileset dir="${lib.dir}">         <include name="**/*.jar"/>     </fileset>     <fileset dir="${common.jar.dir}">         <include name="**/*.jar"/>     </fileset> </path> 

Introducing cross project dependencies like this is not without risk. If you try to build the webapp sub-project before the common project is built, the build will fail because the dependent JAR won't be present. Of course, most other sub-projects will have dependencies on the common project by designthe common project is meant to hold objects that will be shared across all tiers.

Having the webapp sub-project rebuild the common project every time could be an unnecessary step if the common project changes infrequently. If we do not couple the webapp build process to the common build process, webapp developers can informally baseline the common project by only rebuilding it when they make a conscious effort to do so.

Type ant in the webapp top-level directory to build the WAR file. Change to build/distribution and type jar tvf webapp.war to see the contents. Verify that CarDTO is no longer present in the WAR.

3.3.1.3. The master build

To ensure that each project gets builtin the proper orderwe created a master build file. This file doesn't actually compile any code; rather, it calls the appropriate build files of each sub-project in the proper order and then EARs up the results. Any failure of any sub-build will fail the master build, so we can rest assured that a successful master build is predicated on each individual build completing successfully.

To invoke a build script in another directory, we use the <ant> task. Here is what our compile target looks like in the master build.xml file in Example 3-3.

Example 3-3. master build.xml
 <target name="compile" description="Compiles all Java code">         <echo message="##### Building common #####" />         <ant dir="${common.dir}" target="all" >             <property name="jar.name" value="${common.jar.name}"/>         </ant>         <echo message="##### Building webapp #####" />         <ant dir="${webapp.dir}" target="all" >             <property name="war.name" value="${webapp.war.name}"/>             <property name="common.jar.dir" value="${basedir}/${common.jar.dir}"/>         </ant>     </target> 

Notice that we also can override properties in the child build process. In both instances, we override the name of the JAR or WAR file specified in the child build. In the case of the webapp build, we can no longer use the same relative path: your base directory is different now, so trying to move up a level and over doesn't work. We pass the webapp build file a fully qualified path to the common output directory.

3.3.1.4. Ant EAR task

The final step in the process is to EAR up the results of the webapp and common builds. Just as there is a WAR task, Ant also provides us with an EAR task, as in Example 3-4.

Example 3-4. master build.xml
 <target name="ear" depends="compile">         <ear destFile="${distribution.dir}/${ear.name}"              appxml="${meta-inf.dir}/application.xml" >             <!-- files to be included in / -->             <fileset dir="${webapp.war.dir}" />             <fileset dir="${common.jar.dir}" />         </ear>     </target> 

Notice that the EAR task requires us to pass it a well-formed application.xml file. Example 3-5 shows what a simple one looks like.

Example 3-5. application.xml
 <?xml version="1.0" encoding="UTF-8"?> <application xmlns="http://java.sun.com/xml/ns/j2ee"              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"              xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee                  http://java.sun.com/xml/ns/j2ee/application_1_4.xsd"              version="1.4">     <display-name>JBossAtWorkEAR</display-name>     <module>         <web>             <web-uri>webapp.war</web-uri>             <context-root>jaw</context-root>         </web>     </module>     <module>         <java>common.jar</java>     </module> </application> 

To verify the results of the master build, change to the build/distribution directory and type jar tvf jaw.ear. You should see webapp.war, common.jar, and application.xml. We are now ready to deploy the EAR file .



JBoss at Work. A Practical Guide
JBoss at Work: A Practical Guide
ISBN: 0596007345
EAN: 2147483647
Year: 2004
Pages: 197

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net