JaVa
   

Hello World app Project

The goal of the Hello World app project is to create a standalone Java app that uses greetmodel.jar to get the greeting message. The app project buildfile is nearly identical to the model project buildfile, so we focus our discussion on the differences between the two buildfiles. We also explain how to make a JAR file an executable JAR file.

Overview of app Java Classes

The Java source code for this app is as simple as it gets for the Hello World Model 2 examples. Here is the Java app:

package xptoolkit;
import xptoolkit.model.GreetingFactory;
import xptoolkit.model.Greeting;
public class HelloWorld{
 public static void main(String []args)throws Exception{
 Greeting greet = (Greeting) GreetingFactory.getGreetingFactory().getGreeting();
 System.out.println(greet.getGreeting());
 }
}


As you can see, this app imports the GreetingFactory class and the Greeting interface from the model project. It uses the GreetingFactory to get an instance of the Greeting interface, and then uses the instance of the Greeting interface to print the greeting to the console.

Creating a Project Directory Structure for the app

The directory structure of the Hello World Java app is as follows:

Hello World app root
| build.xml
|
+---src
| |
| +---xptoolkit
| HelloWorld.java
|
\---META-INF
 MANIFEST.MF


Notice the addition of the META-INF directory, which holds the name of the manifest file we will use to make the app's JAR file executable. The only other file that this project needs is not shown; the file is greetmodel.jar, which is created by the model project (the reason for this will become obvious in the following sections).

Creating a Manifest File for a Standalone app

The goal of this app is for it to work as a standalone JAR file. To do this, we need to modify the manifest file that the app JAR file uses to include the main class and the dependency on greetmodel.jar. The manifest entries that this app needs look something like this:

Manifest-Version: 1.0
Created-By: Rick Hightower Main-Class: xptoolkit.HelloWorld Class-Path: greetmodel.jar


The Class-Path manifest entry specifies the JAR files that the JAR file that holds the Hello World Java app needs to run (in our case, greetmodel.jar). The Main-Class manifest entry specifies the main class of the JAR fileā€”that is, the class with the main method that is run when the executable JAR file executes.

Creating an Ant Buildfile for a Standalone app

The following listing shows the app project buildfile; you'll notice that it is very similar to the model project buildfile. It is divided into the same targets as the model project buildfile: setProps, init, clean, delete, prepare, mkdir, compile, package, and all. The app project buildfile defines the properties differently, but even the property names are almost identical (compare with the model project buildfile earlier in this chapter).

<project default="all" >
 <target unless="setProps" description="setup the properties.">
<property value="/tmp/app" /> </target>
 <target depends="setProps" description="initialize the properties.">
 <tstamp/>
 <property name="local_outdir" value="${outdir}/java_app" />
 <property value="${local_outdir}/classes" />
 <property value="${outdir}/lib" />
 <property name="app_jar" value="${lib}/greetapp.jar" />
 </target>
 <target depends="init" description="clean up the output directories.">
 <delete dir="${build}" />
 <delete file="${app_jar}" />
 </target>
 <target depends="init" description="prepare the output directory.">
 <mkdir dir="${build}" />
 <mkdir dir="${lib}" />
 </target>
 <target depends="prepare" description="compile the Java source.">
 <javac srcdir="./src" destdir="${build}">
 <classpath >
 <fileset dir="${lib}">
 <include name="**/*.jar"/>
 </fileset>
 </classpath>
 </javac>
 </target>
 <target depends="compile"
 description="package the Java classes into a jar.">
 <jar jarfile="${app_jar}"
 manifest="./META-INF/MANIFEST.MF"
 basedir="${build}" />
 </target>
 <target depends="clean,package" description="perform all targets."/> </project>


One of the differences in the app project buildfile is the way that it compiles the Java source:

 <target depends="prepare" description="compile the Java source.">
 <javac srcdir="./src" destdir="${build}">
 <classpath >
 <fileset dir="${lib}">
 <include name="**/*.jar"/>
 </fileset>
 </classpath>
 </javac>
 </target>


Notice that the compile target specifies all the JAR files in the common lib directory (<include name="**/*.jar"/>). The greetmodel.jar file is in the common lib directory, so it is included when the javac task compiles the source. Another difference is the way the app project's buildfile packages the Ant source as follows:

 <target depends="compile"
 description="package the Java classes into a jar.">
 <jar jarfile="${app_jar}"
 manifest="./META-INF/MANIFEST.MF"
 basedir="${build}" />
 </target>


Notice that the package target uses the jar task as before, but the jar task's manifest is set to the manifest file described earlier. This is unlike the model project buildfile, which did not specify a manifest file; the model used the default manifest file. The app project buildfile's manifest file has the entries that allow us to execute the JAR file from the command line. In order to run the Hello World Java app, after we run the app project's buildfile, we go to the output common lib directory (tmp/app/lib) and run Java from the command line with the -jar command-line argument, as follows:

$ java -jar greetapp.jar Hello World!


You may wonder how it loaded the Greeting interface and GreetingFactory class. This is possible because the manifest entry Class-Path causes the JVM to search for any directory or JAR file that is specified (refer to the JAR file specification included with the Java Platform documentation for more detail). The list of items (directory or JAR files) specified on the Class-Path manifest entry is a relative URI list. Because the greetmodel.jar file is in the same directory (such as /tmp/app/lib) and it is specified on the Class-Path manifest, the JVM finds the classes in greetmodel.jar.

One issue with the app project is its dependence on the model project. The model project must be executed before the app project. How can we manage this? The next section proposes one way to manage the situation with an Ant buildfile.


JaVa
   
Comments