JaVa
   

EAR Enterprise app

In addition to having a master buildfile called main (we discussed the master buildfile in ), we want to deploy all our apps into an app server that can accept them. The main buildfile serves two purposes:

The HelloWorld Main Project Buildfile

The main project's buildfile is structured (not surprisingly, we hope) very much like the other buildfiles. There are setProps, init, prepare, clean, build, and package targets. One of the key differences is that the main buildfile delegates the clean and build targets to the subproject while ensuring that they execute in the correct order. Also, the package section creates an EAR file. Refer to the following listing to see the final main buildfile.

<project default="package" >
 <target unless="setProps" description="setup the properites.">
 <property value="/tmp/app" /> <property value="true" />
 </target>
 <target depends="setProps" 
 description="initialize the properties.">
 <tstamp/>
 <property value="${outdir}/dist" />
 <property value="${outdir}/deploy" />
 <property value="${outdir}/classes" />
 <property value="${outdir}/lib" />
 </target>
 <target depends="init" description="clean up the output directories.">
 <ant dir="./Model" target="clean">
 <property value="${outdir}" />
 <property value="true" />
 </ant>
 <ant dir="./EJBeans" target="clean">
 <property value="${outdir}" />
 <property value="true" />
 <property value="/tools/jboss/jboss/deploy" />
 </ant>
 <ant dir="./Webapp" target="clean">
 <property value="${outdir}" />
 <property value="true" />
 <property value="true" />
 </ant>
 <ant dir="./app" target="clean">
 <property value="${outdir}" />
 <property value="true" />
 </ant>
 <delete dir="${outdir}" />
 </target>
 <target depends="init" description="prepare the output directory.">
 <mkdir dir="${build}" />
 <mkdir dir="${lib}" />
 <mkdir dir="${dist}" />
 <mkdir dir="${deploy}" />
 <mkdir dir="${dist}/META-INF" />
 </target>
 <target depends="prepare" description="build the model and app modules.">
 <ant dir="./Model" target="package">
 <property value="${outdir}" />
 <property value="true" />
 </ant>
 <ant dir="./EJBeans" target="deploy">
 <property value="${outdir}" />
 <property value="true" />
 <property value="/tools/jboss/jboss/deploy" />
 </ant>
 <ant dir="./Applet" target="package">
 <property value="${outdir}" />
 <property value="true" />
 </ant>
 <ant dir="./Webapp" target="deploy">
 <property value="${outdir}" />
 <property value="true" />
 <property value="true" />
 </ant>
 <ant dir="./app" target="package">
 <property value="${outdir}" />
 <property value="true" />
 </ant>
 </target>
 <target depends="build">
 <copy file="./META-INF/app.xml" todir="${dist}/META-INF" />
 <jar jarfile="${deploy}/hello.ear" basedir="${dist}" />
 </target>
</project>


Analyzing the Buildfile for the Enterprise app

The build target uses the ant task (<ant…>) to call the other Ant buildfiles. The build target is as follows:

 <target depends="prepare" description="build the model and app modules.">
 <ant dir="./Model" target="package">
 <property value="${outdir}" />
 <property value="true" />
 </ant>
 <ant dir="./EJBeans" target="deploy">
 <property value="${outdir}" />
 <property value="true" />
 <property value="/tools/jboss/jboss/deploy" />
 </ant>
 <ant dir="./Applet" target="package">
 <property value="${outdir}" />
 <property value="true" />
 </ant>
 <ant dir="./Webapp" target="deploy">
 <property value="${outdir}" />
 <property value="true" />
 <property value="true" />
 </ant>
 <ant dir="./app" target="package">
 <property value="${outdir}" />
 <property value="true" />
 </ant>
 </target>


Notice that each call to invoke another buildfile sets the relative directory of the subproject's buildfile (<ant dir="./Model" target="package">) and the target of the buildfile. Because we named each buildfile of each subproject build.xml, we only need to specify the directory. In addition to specifying the target that we want to execute, the ant task passes two properties to each subproject, as follows:

 <property value="${outdir}" />
 <property value="true" />


The second property ensures that the subproject's setProps target is not executed, by setting the property "setProps". Remember, the "setProps" property for each project is not executed if the setProps property is set (<target unless="setProps">). The first property ensures that the value of the outdir of the main project is passed to the subproject. When we combine these two properties, it's easy to set a new directory for all the output of the main project and all its subprojects at the command line, demonstrated (using bash) as follows:

rick@CANIS_MAJOR /usr/rick/cvs/XPToolKit/examples/chap5/MVCHelloWorld
$ ant -DsetProps=no -Doutdir=/usr/rick/output


These lines could be used to redirect the output to a directory to which you have access, if you are developing on a Unix box. The clean target follows many of the same concepts as the build target, so we will not discuss it in detail. The next major piece of the main project is the package target, as follows:

 <target depends="build">
 <copy file="./META-INF/app.xml" todir="${dist}/META-INF" />
 <jar jarfile="${deploy}/hello.ear" basedir="${dist}" />
 </target>


This code copies the app.xml metadata from the ./META-INF directory to the distribution directory. The distribution directory is also where the webapp project buildfile's package target and the enterprise beans project buildfile's package target put their WAR and EJB JAR file, respectively. The next task is for the main's package target to jar the WAR, EJ JAR, and app.xml files into a JAR file format. It does this with the jar task, as follows:

 <jar jarfile="${deploy}/hello.ear" basedir="${dist}" />


The output of the file is hello.ear, which is put into the deployment directory. The deployment directory is defined in the init target (for example, /tmp/deploy). The app.xml file is the deployment descriptor for the EAR file.

Enterprise app Deployment Descriptor

If our intention is to deploy the Web app and the enterprise beans as a single logical unit, it may be useful to create an EAR file as we did. In order for the J2EE container to understand what we are deploying, we have to tell it with the deployment descriptor in the following listing.

<app>
 <display-name>Hello World app</display-name>
 <description>Hello World app.</description>
 <module>
 <web>
 <web-uri>hello.war</web-uri>
 <context-root>helloworld</context-root>
 </web>
 </module>
 <module>
 <ejb>greet-ejbs.jar</ejb>
 </module>
</app>


Looking at this code, you may wonder why we don't list the model library, the applet JAR, the enterprise bean client JAR, and so on. Remember, they were included with the WAR file. Instead, the deployment descriptor describes two modules: our Hello World Web app and our Hello World enterprise beans. First the Web app:

 <module>
 <web>
 <web-uri>hello.war</web-uri>
 <context-root>helloworld</context-root>
 </web>
 </module>


Notice that the URI for the Web app is set to helloworld; thus, when we deploy it, it runs under the helloworld directory (http://localhost/helloworld). Next, we defined the Enterprise JavaBean module as follows:

 <web>
 <web-uri>hello.war</web-uri>
 <context-root>helloworld</context-root>
 </web>


We can use it to deploy in one simple step to any J2EE container that supports both Web apps and enterprise beans.


JaVa
   
Comments