The Server Labs Blog Rotating Header Image

Compile-time architecture enforcement revisited: AspectJ, Maven and Eclipse

It has been a while since we first heard about compile-time checks with AspectJ at the Java Server Symposium in 2007. Since then we have been using and experimenting with this feature of AOP and AspectJ, and more recently we have used this technology to implement architecture enforcment rules for some of our clients.

In this more technical post we revisit the concepts, how to create Aspects, and more importantly, how we integrate the aspect libraries with Maven and Eclipse via AspectJTools, creating an easy to maintain and usable environment.

We apply an agile approach in most of our projects, so what we describe here allow us to automate and integrate the architecture enforcement rules into our continuous integration environment using maven, meaning that we can fail a build that does not meet our architecture rules.

Depending on project’s nature, the enforcement rules may vary but they normally fall into some or all of these categories:

  • Rules to enforce application architecture and layering
  • Rules to enforce good practices like:
    • Usage of utility libraries against direct data manipulations
    • Exception handling
    • Proper logging against dumps to console
  • Avoid usage of already know problematic libraries

The ideal way to put all of this to work is to organise the defined rules in different libraries, so we can reuse them based on the type of project we are currently working on. Moreover, how can we setup maven projects/archetypes and Eclipse to use the configured environment automatically?

Preparing the rules libraries:

  1. Creation of maven project and codification of the rules in AspectJ aspects.
  2. Compile and archive the rules libraries.

Setup of the development environment:

  1. Configuring maven projects or archetypes that make use of the rules libraries.
  2. Automatically configure AspectJ Tools for Eclipse.

Let’s start on how we can create AspectJ aspects libraries to code the enforcing rules.

Preparing the rules libraries:

  • Create a maven project using a standard archetype:
$mvn archetype:create –DgroupId=com.tsl.common –DartifactId=lib-aoprules-enforce

We need to add the following the dependencies for AspectJ libraries and the aspectj-maven-plugin to the generated pom.xml in order to enable the compilation of AspectJ aspects. Te final pom.xml is given below:


	4.0.0
	com.tsl.common
	lib-aoprules-enforce
	jar
	1.0-SNAPSHOT
	lib-aoprules-enforce
	http://maven.apache.org
	
	   
		org.aspectj
		aspectjrt
		1.5.4
	   
	
	
	   
	      
		   org.apache.maven.plugins
		   maven-eclipse-plugin
		   2.6-SNAPSHOT
	      
	      
		  org.codehaus.mojo
		  aspectj-maven-plugin
		  
			
				
					compile
				
			
		  
	      
	  
	
	
           
  		apache.snapshots
		Apache Snapshot Repository
		
			http://people.apache.org/maven-snapshot-repository
		
		
			true
		
		
			false
		
          
       

Additionally, we have added another specific entry for the maven-eclipse-plugin. Why? Well, the current version of maven-eclipse-plugin (2.5.1) does not generate any configuration parameters to configure AspectJTools for Eclipse, i.e. project nature in “.project” file and AspectJ classpath in “.classpath” file.

A few days ago, the enhancement was added to the 2.6 snapshot version and works perfectly.

This allows us to use the maven-eclipse-plugin goal eclipse:eclipse to generate all necessary aspectj tools classpath variables and project natures.
You can download the snapshot from the apache repository and include it into your maven repo (see the plugin-repository definition in pom.xml).

So, let´s execute mvn eclipse:eclipse in the project directory and import the project into Eclipse (I´m asumming the M2_REPO classpath variable is already configured in your Eclipse environment and the AspectJTools pluging for Eclipse has been installed). Note how the AspectJ nature is already enabled. Later, when we want to make use of the libraries, we will see that the enhancement has another feature to make life easier.

Now, we can create a new aspect called “EnforceLogging.aj” in Eclipse. This aspect codifies a rule that will detect and generate a compilation warning of all calls that print to console outside TestCase classes, considering that our unit test framework is Junit:

package com.tsl.enforcement.aspects;

import junit.framework.*;

public aspect EnforceLogging {

	pointcut scope():
		within(com.tsl..*) && !within(TestCase+);

	pointcut printing(): 
		get(* System.out) || get(* System.err) || call(* printStackTrace());

	declare warning
		: scope() && printing()
		: "Don't print to Console, use logger";

}

As we are using Junit libraries in our aspects we need to add it as a dependency to the maven pom.

With this configuration, we can easily build now our first rules library and deploy it in our repository with mvn install.

Setup of development environment:

Let’s see how a new project will be created and how it will use those rules libraries.
As we use maven, the integration is pretty simple and will ensure that our continuous integration system will detect builds that break the configured rules.

In the past, we would have to manually configure the AspectJTools plugin in Eclipse to work with our project – which can be very annoying.

As mentioned previously, now with the 2.6 version of the maven-eclipse-plugin, we can integrate everything in a transparent way to the developer, so they can start coding in Eclipse without worrying about AspectJ details.

We normally have a maven archetype defined with the required configuration to enable aspectj and the libraries we want to be included, so the development team will create a new project with all the desired enforcement rules straight away.

For this example, a project pom.xml from which the archetype could be generated should include at least:


	4.0.0
	com.tsl.common
	enforcement-test
	jar
	1.0-SNAPSHOT
	enforcement-test
	http://maven.apache.org
	
		
			com.tsl.common
			lib-aoprules-enforce
			1.0-SNAPSHOT
		
		
			org.aspectj
			aspectjrt
			1.5.4
		
	
	
	   
	      
		org.apache.maven.plugins
		maven-eclipse-plugin
		2.6-SNAPSHOT
	      
	      
		org.codehaus.mojo
		aspectj-maven-plugin
		
			
				
					
						com.tsl.common
					
					
						lib-aoprules-enforce
					
				
			
		


		
			
				
					compile
				
			
		
	      
          
	
	
           
  		apache.snapshots
		Apache Snapshot Repository
		
			http://people.apache.org/maven-snapshot-repository
		
		
			true
		
		
			false
		
          
       


The dependencies must include the aspects library or libraries together with the aspectj runtime library. In the other hand, the aspectj-maven-plugin configuration must include those libraries when weaving.

Now, if we execute mvn eclipse:eclipse and import the project in Eclipse we can create an example class that violates the defined rule, verifying that we get compile errors:

AspectJ compile-time checks in eclipse

Note that the AspectJ Libraries have been atuomatically configured for us in “Referenced Libraries”.

That´s it, with this setup we can define an easy to use and easy to maintain architecture/best practices enforcement for all our projects.

Consider that this is a simple example and depending on the environment you might want to setup different profiles to activate these compile-time checks at development time and avoid dragging the aspectjrt library into production builds. We normally use it for our development and integration builds, while disabling it for the production builds.

Some additional things to consider:

  • As Olivier mentions in his blog entry, there are some cases (e.g. two maven compile executions without changes in the source or configuration) where the aspectj compilation is not performed and therefore errors/warnings might be bypassed. There was an enhancement request but I haven’t seen it included in any release or snapshots. In the end, it is not a major problem, it does not affect the development environment with Eclipse, and we normally enforce a mvn clean in our continuous integration which gets around the problem.
  • The aspect libraries must be generated with the same compiler than later is used to weave the classes.

4 Comments

  1. Sanjay Acharya says:

    Very nice blog post. Thanks much for the excellent explanation.

  2. sandrar says:

    Hi! I was surfing and found your blog post… nice! I love your blog. :) Cheers! Sandra. R.

  3. Krish says:

    I was able to get it working with maven, but with ant it fails…not the expected output, doesn’t seem to do anything..I think i’ve messed up with aj5. Thanks for the post.

  4. Jan says:

    i’m planning to create a similar process in our organisation, ie develop some aspects to enforce correct coding.

    Are there more examples available or maybe an opensource project which has some ready to use aspects allready?

    I would hate to reinvent the wheel..

Leave a Reply

Your email address will not be published. Required fields are marked *