Mavenizing an existing project

At work, with about a hundred applications running, have started a mavenizing project. Diversity is a rule when it comes to used technologies and techniques in the building of those systems, but I’ll try to expose a common scenario: an old plain ejb2 project that uses XDoclet to generate interfaces code.

Preparing the code.

First thing first. If the code is managed by a SCM, which hopefully is, make a branch before you start.

Standard directory structure.

Once you are ready to work, begin by changing the directory structure to maven standard. You could leave it your way and make a few adjustments in the project’s descriptor later, but if you’re planning to have an enterprise project to define basic services for all projects like common dependencies and distribution management, you should stick to the maven way.

So, in your project’s base directory make the following dirs

  • src/main/java
  • src/main/java/resources
  • src/test/java
  • src/test/java/resources

If you are working inside Eclipse IDE, right click your project and open the project’s properties. Go to the Java Build Path option and click the Source tab. Delete the current source folders and add src/main/java and src/test/java as the new source folders.

Now, move all you code to src/main/java, e.g. src/ec/pazmino/example moves to src/main/java/ec/pazmino/example

Move everything you need to have inside the classpath to src/main/java/resources, e.g. src/jndi.properties moves to src/main/java/resources/jndi.properties

Finally, move your test code and resources src/test/java and src/test/java/resources

Enable dependency mananagement.

In your project’s base directory add a pom.xml file and set your your project’s maven coordinates. Eclipse users may right click your project and select Maven -> Enable Dependency Management to create the pom.xml file. After you’ve entered your project’s info, list your lib directory so you know all the libraries your project depends on. Every library in the list must be added to the pom’s <dependencies> list. Make sure you use the right version and the right scope. Now, analyze your dependencies with mvn dependency:analyze Once executed, delete from the <dependencies> list every library under [WARNING] Unused declared dependencies found:

Code generation with maven-xdoclet-plugin.
We’ll go with an incremental approach on the plugin’s configuration so it’s easier to follow. Add the maven-xdoclet-plugin to your pom

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xdoclet-maven-plugin</artifactId>
<version>1.0</version>
</plugin>

Add the place-holder for the task it should perform

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xdoclet-maven-plugin</artifactId>
<version>${plugin.maven.xdoclet.version}</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>xdoclet</goal>
</goals>
<configuration>
<tasks>
</tasks>
</configuration>
</execution>
</executions>
</plugin>

Now, open your build.xml and copy everything inside the <ejbdoclet> task to the <tasks> place-holder in your pom. Replace ant-like paths for maven-like ones, e.g. ${gen-src.ejb.dir} changes to ${project.build.directory}/main/java

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xdoclet-maven-plugin</artifactId>
<version>${plugin.maven.xdoclet.version}</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>xdoclet</goal>
</goals>
<configuration>
<tasks>
<ejbdoclet destdir="${project.build.directory}/main/java" mergedir="${project.build.outputDirectory}" excludedtags="@version,@author,@todo" ejbspec="2.0" force="${plugin.maven.xdoclet.force}">
<fileset dir="${project.build.sourceDirectory}">
<include name="**/ejb/**/*Bean.java" />
</fileset>
<packageSubstitution packages="beans" substituteWith="interfaces" />
<localinterface />
<remoteinterface />
<homeinterface />
<localhomeinterface />
<session />
<entitypk />
<entitycmp />
<valueobject />
<utilobject kind="physical" cacheHomes="true" />
<deploymentdescriptor destdir="${project.build.outputDirectory}/META-INF" xmlencoding="ISO-8859-1" validateXML="true" />
<jboss version="3.2" destdir="${project.build.outputDirectory}/META-INF" datasource="${jboss.datasource}" datasourcemapping="${jboss.datasource.mapping}" xmlencoding="ISO-8859-1" validateXML="true" />
</ejbdoclet>
</tasks>
</configuration>
</execution>
</executions>
</plugin>

Since we are generating code inside ${project.build.directory}/main/java we need to make this source available to the compilation goal before it begins, here we need some help from the build-helper-maven-plugin. Eclipse users should add this directory to the source folders.

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>${plugin.maven.helper.build}</version>
<executions>
<execution>
<id>gen-src</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/main/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>

Building the artifact

mvn install

Reusing config

Move you plugins configuration to a legacy-app profile inside $M2_HOME/conf/settings.xml or a parent pom and make it available for every other project. Build it with

mvn isntall -Plegacy-app

Advertisements

2 responses to “Mavenizing an existing project

  1. mvn=XML hell, 🙂

    chebre, testing

  2. Nice job, very useful article.
    Another interesting tutorial about the build-helper-maven plugin i found useful.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s