Maven 3 and java.net Maven 1 artifacts

Recently I needed to debug some features on JOSSO. So I checked out the source and started to build the project. At some point, it starts to nag about it cannot resolve some artifact because it wants to download some dependency from java.net Maven/1 repository layout:

(http://download.java.net/maven/1): No connector available to access repository java.net

After a couple of hours of searching and trying different things, the workaround for me is to download Apache Maven 2 and use it to build the project. I originally tried building the source with Apache Maven 3. The point is that although the project may specify legacy option on some dependencies, it does not work with Apache Maven 3.

Maven repository to OSGi Bundle Repository

Recently, I’ve had the chance to start to work with OSGi. One of the first things that I faces was how I can prepare a local Maven repository as a local OSGi Bundle Repository (OBR). The central concept is to maintain a repository.xml as the OBR descriptor. There are several ways to do so including manually doing it. I just found out that Apache Felix has a Maven plugin called maven-bundle-plugin. In the latest version of this plugin, there is a goal bundle:index. On a project configured with you Maven repository, first configure this plugin and then run:

[plain]
mvn bundle:index
[/plain]

This will generate a repository.xml at the root of your Maven repository. Then you can use that to feed the OSGi container that you use for bundle provisioning.

Customized WAR/JAR with Maven Multiple Modules

Maven provides a clean way to create multi-module projects such that using the natural style of POM’s will mange the way the final artifacts are bundled and released. However, dealing with non-standard project structure, there are situations that we need to tweak how the project artifacts in a multi-module project are created. In this post, we go through how this is done using Maven Resources Plugin, Maven Jar Plugin, and Maven Dependency Plugin.

The project layout we use is as follows:

  • parent: is the POM project that is the parent of all projects defining the common dependencies and properties
  • foo: is a child project of parent that is for instance provides some architectural API and other resources for other web-based modules
  • bar: is a child project of parent that is a web module dependent on foo and provides some business specific features

In this setup, the final purpose is to build a web archive (war) for bar that selectively uses some features from foo. On the other hand, let’s assume that foo provides three different set of features provided as artifacts:

  • API: a set of classes that is used by other child projects of parent such as bar
  • configs: a set of configuration files and other resources that is needed to deploy when some other child uses foo; e.g. some Spring or Hibernate configuration files in the final artifact
  • web: a set of common web resources that is used by other child projects; e.g. table list templates or common images for web modules

The steps that are required to produce the final bar war artifact are:

  1. We use maven-resources-plugin to copy the resources into the desired locations for being bundles as separate artifacts (foo)
  2. We use maven-jar-plugin to create different artifacts (jar files) such that they can be used independently (foo)
  3. We use maven-dependency-plugin to again include the different artifacts of foo in the desired location to be bundles as a whole war artifact

For the first step, we use maven-resources-plugin to copy for instance the desired resourced into the location that should be considered when packaging the artifacts for foo. We bind the configuration to “prepare-package” phase:

[xml]
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-configs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/classes/WEB-INF/configs</outputDirectory>
<resources>
<resource>
<directory>src/main/java</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-web</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/classes/WEB-INF/views</outputDirectory>
<resources>
<resource>
<directory>src/main/webapp</directory>
<filtering>true</filtering>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
[/xml]

For the second step, we defined multiple artifact using the “classifier” option in the maven-jar-plugin. This will install different JAR files as the artifacts of foo to be used in dependent projects:

[xml]
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>api</id>
<goals>
<goal>jar</goal>
</goals>
<phase>package</phase>
<configuration>
<classifier>api</classifier>
<includes>
<include>**/*.class</include>
</includes>
</configuration>
</execution>
<execution>
<id>web</id>
<goals>
<goal>jar</goal>
</goals>
<phase>package</phase>
<configuration>
<classifier>web</classifier>
<includes>
<include>WEB-INF/views/**/*.*</include>
</includes>
</configuration>
</execution>
<execution>
<id>configs</id>
<goals>
<goal>jar</goal>
</goals>
<phase>package</phase>
<configuration>
<classifier>configs</classifier>
<includes>
<include>WEB-INF/configs/**/*.*</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
[/xml]

For the third step, we use maven-dependency-plugin to include and unpack the desired artifacts from foo in the bar packaging process such that the final artifact of bar includes the required resources from foo:

[xml]
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>unpack</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>nl.hmsolutions</groupId>
<artifactId>core</artifactId>
<version>1.0</version>
<classifier>web</classifier>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}/${project.artifactId}-${project.version}</outputDirectory>
<includes>**/*.*</includes>
</artifactItem>
</artifactItems>
<includes>**/*.*</includes>
<outputDirectory>${project.build.directory}/${project.artifactId}-${project.version}</outputDirectory>
<overWriteReleases>false</overWriteReleases>
</configuration>
</execution>
</executions>
</plugin>
[/xml]

Finally, in the “${basedir}/target/bar-1.0”, we can find the final war archive including all the resources and classes for the project.