Section 6.7. Implementing the Logifier Build Logic


6.7. Implementing the Logifier Build Logic

You've discovered how to write the Logging Aspect and how to bundle this Aspect as a plug-in resource. Now, you'll need to implement the plug-in logic to weave the Aspect into the Java .class files and generate a "logified" JAR.

6.7.1. How do I do that?

Luckily, the AspectJ framework has an iajc Ant task that can weave any Aspect onto a set of Java source files, JAR files, or Java bytecode (.class files).

In this plug-in, you'll weave the Logging Aspect onto .class files. Here's the part of your plugin.jelly file that weaves the Aspect and generates the logified JAR:

<?xml version="1.0"?>    <project     xmlns:j="jelly:core"     xmlns:ant="jelly:ant"     xmlns:maven="jelly:maven">      <goal name="logifier:compile" prereqs="java:compile">        <ant:iajc destDir="${maven.build.dest}">       <ant:sourceroots>         <ant:pathelement location="${plugin.resources}/aspect"/>       </ant:sourceroots>       <ant:inpath>         <ant:pathelement location="${maven.build.dest}"/>       </ant:inpath>       <ant:classpath>         <ant:path ref/>         <ant:pathelement              path="${plugin.getDependencyPath('aspectj:aspectjrt')}"/>       </ant:classpath>     </ant:iajc>        </goal>      <goal name="logifier:logify" prereqs="logifier:compile,jar"       description="Generate a logified JAR"/>   </project>


Tip: There is an AspectJ plug-in that you can use to weave Aspects onto your code. You should normally use it to weave Aspects. However, reusing the AspectJ plug-in from the Logifier plug-in is not possible because it has not been designed to be reused by other plug-ins. Note that when you use the AspectJ plug-in you define the location of your Aspects by setting the aspectSourceDirectory tag located under the build tag in your project's POM.

You have created two goals: logifier:compile and logifier:logify. The logifier:compile goal calls java:compile to compile the Java source files into .class files, and the iajc Ant task weaves the Aspect onto these .class files. The logifier:logify goal is in charge of generating the "logified" JAR: it does this very simply by calling the JAR plug-in.

The iajc Ant task is an Ant task that you can find in the AspectJ aspectjtools.jar JAR, located in AspectJ's distribution. The destDir attribute specifies where the weaved .class files will be output. Note that you are overwriting the existing .class files generated by java:compile. That makes it simpler to reuse the JAR plug-in afterward (you don't have to tell it to look for .class files in a location different from its default).

You specify the location of your Aspect definitions using the sourceroots Ant PATH element, and you specify the source .class files to weave onto using the inpath PATH element.

Now here's something interestingreferencing a dependency defined in project.xml from within your project.jelly file. You do this using the geTDependencyPath( ) method on the plugin object (this is a Java object representing the plug-in POM), passing to it a string with the format groupId:artifactId. Here you're referencing the aspectj:aspectjrt artifact which needs to be defined in the plug-in's project.xml as follows (1.2.1 is the latest version at the time of this writing):

  <dependencies>     <dependency>       <groupId>aspectj</groupId>       <artifactId>aspectjrt</artifactId>       <version>1.2.1</version>     </dependency>

This aspectjrt.jar JAR is required for weaving by the iajc task.

But, hey, hold on! There is something missing. Where have you defined the iajc Ant task? It's not part of the standard Ant distribution (the one bundled with Maven), and thus you need to introduce it via the taskdef Ant task, as you would for any custom Ant task! To successfully define this task, you will also need to add the aspectjtools.jar JAR to the classpath, as the iajc task depends on it. Refactor the plugin.jelly file to add a logifier:init goal to taskdef the iajc task as follows:

<?xml version="1.0"?>    <project     xmlns:j="jelly:core"     xmlns:ant="jelly:ant"     xmlns:maven="jelly:maven">      <goal name="logifier:init">         <ant:taskdef          resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties">       <ant:classpath>         <ant:pathelement              path="${plugin.getDependencyPath('aspectj:aspectjtools')}"/>       </ant:classpath>     </ant:taskdef>       </goal>      <goal name="logifier:compile" prereqs="logifier:init,java:compile">        <ant:iajc destDir="${maven.build.dest}">  [...]

You'll need to add a reference to the aspectjtools artifact in your project.xml file, and by now you should be familiar with the steps involved in adding dependencies. Here's the new dependency from project.xml:

  <dependencies>     <dependency>       <groupId>aspectj</groupId>       <artifactId>aspectjrt</artifactId>       <version>1.2.1</version>     </dependency>     <dependency>       <groupId>aspectj</groupId>       <artifactId>aspectjtools</artifactId>       <version>1.2.1</version>     </dependency>   </dependencies>

You are almost there. One little detail remains... Remember this aspectjrt JAR? Well, as its name implies (rt stands for runtime) it is required to be in the classpath when executing the "logified" JAR. Yuck! That's not cool, as any Maven project that wants to use your "logified" plug-in will also need to add the aspectjrt JAR to its dependency list... But there's a solution! Why not bundle the aspectjrt JAR into the "logified" JAR? This would work, except in the very unlikely case where the Maven project is already using a different version of AspectJ than the version used by the Logifier. But, if that were the case, you wouldn't need to bundle aspectjrt JAR at all!

You can easily add the aspectjrt class files to your JAR file by adding the following ant:jar task to update the contents of your project's JAR artifact. Executing the jar task in update mode adds the contents of the aspectjrt JAR:

  <goal name="logifier:logify" prereqs="logifier:compile,jar"       description="Generate a logified JAR">        <maven:get var="jarName" plugin="maven-jar-plugin"          property="maven.jar.final.name"/>     <j:set var="jar" value="${maven.build.dir}/${jarName}"/>         <ant:jar destfile="${jar}" update="true">       <ant:zipfileset            src="/books/2/791/1/html/2/${plugin.getDependencyPath('aspectj:aspectjrt')}"/>     </ant:jar>       </goal>

Simple, isn't it?



Maven. A Developer's Notebook
Maven: A Developers Notebook (Developers Notebooks)
ISBN: 0596007507
EAN: 2147483647
Year: 2003
Pages: 125

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