|
Building the EJB jars
After having built the dependency jars let us turn our focus to building the ejb jars. This is no different, since there is already a ejb plugin and you can use the ejb:install goal to create and publish the ejb jars. However we would also like to remind you that the ejb jar (loaded by the EJB class loader) depends on the Services built in the previous step (See Figure 4). What this means for you is that the ejb manifest classpath should point to the foobar-services-2.0 jar. Listing 9 shows the project.xml for the Reservation EJB jar. Other ejb project definitions are similar.
NOTE: In the downloadable example supplied with this article, no EJBs are included. The reason is to have even non-ejb developers using Tomcat to see Maven in action. However this section describes what it takes to build EJBs with Maven.
As usual the ejb project depends on the J2EE jars. However since it also depends on the foobar-services-2.0.jar (loaded by the EAR class loader), it has to add that jar file name to its manifest classpath. You can achieve this by setting the property ejb.manifest.classpath to be true. The Maven variable, pom.currentVersion stands for the current version of the project. In our case, it is 2.0. This setting indicates that the version of services project on which the ejb project depends is the same as the current version of the ejb project. This version is set on the parent project template. For future releases, the version number need not be changed for every dependency in every project. Just change it in the Master project template and it takes effect everywhere. Ah, the beauty of inheritance!
Listing 9 Reservation EJB Project Definition
<project>
<extend>${basedir}/../project.xml</extend>
<id>reservationejb</id>
<name>Foobar Reservation Components</name>
<package>foobar.reservation.*</package>
<description>Reservation Components project</description>
<dependencies>
<dependency>
<groupId>j2ee</groupId>
<artifactId>j2ee</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>Foobar-Travels</groupId>
<artifactId>foobar-services</artifactId>
<version>${pom.currentVersion}</version>
<properties>
<ejb.manifest.classpath>true</ejb.manifest.classpath>
</properties>
</dependency>
</dependencies>
</project>
The discussion of building the ejb jars is incomplete without mentioning the maven.xml file. This file is not straight forward as in the services project. Listing 10 shows the maven.xml for the Reservation EJB project. There are a few things happening here. First, the foobar-dist goal is used as a wrapper for attaining the goal ejb:install. One of the first goals to be achieved during the install is init, when the file system and other resources are initialized and then the ejb classes are compiled. The compiler expects to find the home, local and remote interfaces, failing which it will throw a compiler error. This is where XDoclet comes into play.
Listing 10 maven.xml for the Reservation EJB Project
<project default="foobar-dist" xmlns:m="jelly:maven"
xmlns:ant="jelly:ant">
<goal name="foobar-dist">
<attainGoal name="ejb:install" />
</goal>
<preGoal name="ejb:init">
<attainGoal name="xdoclet:ejbdoclet"/>
</preGoal>
<postGoal name="ejb:install">
<ant roperty name="maven.ejb.install.dir"
value="${maven.repo.local}/${pom.artifactDirectory}/ejbs"/>
<ant:mkdir dir="${maven.ejb.install.dir}"/>
<ant:copy file="${maven.build.dir}/${maven.final.name}.jar"
tofile="${maven.ejb.install.dir}/../
jars/${maven.final.name}.jar"/>
</postGoal>
</project>
XDoclet is an open source project hosted on the SourceForge. By using EJB Doclet specific tags in the Bean class (the implementation class), you signal the XDoclet to generate the home, local and remote interfaces. You will also provide the jndi names, and other information using similar tags. On parsing the file, the XDoclet will also generate appropriate deployment descriptors. Now let us get back to see how it fits in here.
XDoclet provides Maven plugins for generating the above-mentioned artifacts. By specifying the ejbdoclet as the preGoal for ejb:init, you will generate home, local and remote interfaces and xml deployment descriptors just in time for the compilation.
Now let us look at the postGoal for ejb:install. As you know, the ejb:install generates the ejb jar as the artifact and puts it in the repository in the location "C:/Documents And Settings/<login-id>/.maven/repository/Foobar-Online/jars". Suppose that you want the ejbs to be in a separate directory called ejbs instead of the jars, you have to do it after the ejb:install is finished with its business. That's why it is a postGoal. For those familiar with Ant, the postGoal is nothing but a collection of Ant tasks. Again, a couple of Maven specific properties are used. Don't try to remember all of the Maven defined properties at once. Over time, these will become second nature.
You will notice there are two distinct categories of properties - those with their name beginning with pom and the rest of them. The properties with their names beginning with pom are the individual elements in the project.xml. For instance, the currentVersion element defined in project.xml has a property with the name pom.currentVersion and so on. The project.xml is loaded to create the POM model by Maven. POM model attribute values are evaluated by using the $ sign before the attribute names. As more plugins are added new properties emerge. This is going to be a challenge. You may not find adequate documentation of these properties. The only way to find out is by opening the scripts for each of these plugins in plugin.jelly file. Luckily there aren't very many properties that you will have to know.
In your project, if you find yourself writing the same pregoals and postgoals for every ejb subproject for example, it is time to roll your own plugin. |
|