How To Reuse Java EE 6 WAR Code With Maven (3)

In Java EE 6 WAR is the new EAR. A WAR, however, is entirely "installed" to the maven 3 repo. It's contents (like JAXB-DTOs), cannot be reused from other applications.
Configuration of maven-jar-plugin and maven-install-plugin solves the issue. The first plugin creates a JAR and the latter installs it into the local repo:


...
<plugins>
<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-jar-plugin</artifactId>
   <executions>
       <execution>
           <id>make-jar</id>
           <phase>compile</phase>
           <goals>
               <goal>jar</goal>
           </goals>
       </execution>
   </executions>
</plugin>
<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-install-plugin</artifactId>
   <executions>
       <execution>
           <id>install-jar</id>
           <phase>install</phase>
           <goals>
               <goal>install-file</goal>
           </goals>
           <configuration>
               <packaging>jar</packaging>
               <artifactId>${project.artifactId}</artifactId>
               <groupId>${project.groupId}</groupId>
               <version>${project.version}</version>
               <file>${project.build.directory}/${project.build.finalName}.jar</file>
           </configuration>
       </execution>
   </executions>
</plugin>
...
</plugins>

After configuration of both plugins, WAR contents are redundantly stored as JAR in the local maven repository and are accessible to other projects by specifying a "usual" dependency to it.

You could also use the attachClasses tag to deploy the jar in addition to the WAR with the "classes" classifier (as suggested by struberg):

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-war-plugin</artifactId>
   <version>2.1.1</version>
   <configuration>
      <attachClasses>true</attachClasses>

But then you will also have to specify the classifier in the dependency:

<dependency>
    <groupId>...</groupId>
    <artifactId>...</artifactId>
    <version>...</version>
   <classifier>classes</classifier>
    <scope>test</scope>
</dependency>

Comments:

While this is possible the better practice is to have a normal (jar) project for your code and have a separate project that builds the war file. Typically you will split any real world project into several projects anyway.

Posted by Christian Schneider on June 10, 2011 at 02:27 PM CEST #

why so complicated?

just tell the maven-war-plugin [1] to
<configuration>
<attachClasses>true</attachClasses>
<archiveClasses>true</archiveClasses>
</configuration>

This will package all classes which would normally land in WEB-INF/classes as separate jar and serve it as 'attached artifact' [2]. You can then reference this 'attached artifact' as normal dependency by just using the proper <classifier> in your targets<dependency> section.

LieGrue,
strub

[1] http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html
[2] http://docs.codehaus.org/display/MAVEN/Packaging+vs+Type+-+Derived+and+Attached+Artifacts
LieGrue,
strub

Posted by struberg on June 10, 2011 at 03:14 PM CEST #

Hi Adam

For me, your proposal looks like a fight against Maven. If some part of the application is needed outside, put it into separate Maven module.

WAR packaging does not mean that you can not modularize application :-)

Posted by Marcin on June 10, 2011 at 03:42 PM CEST #

@Christian,

"...Typically you will split any real world project into several projects anyway."

As described here: http://www.adam-bien.com/roller/abien/entry/is_java_ee_6_war

In this case I do not want any additional JARs or modules and would like to keep everything in one place.

But you are right: in most of my projects we have multiple JARs linked to a single WAR.

thanks!,

adam

Posted by Adam Bien on June 10, 2011 at 07:38 PM CEST #

@Struberg,

attachClasses is a good point -> it made my post longer :-).

thanks!,

adam

Posted by Adam Bien on June 10, 2011 at 07:39 PM CEST #

@Marcin,

"For me, your proposal looks like a fight against Maven"

In this case I only need a few classes for a system test. It is a corner case. If the content were more interesting for other applications I would externalize them as described here: http://www.adam-bien.com/roller/abien/entry/is_java_ee_6_war

Thanks for your comment!,

adam

Posted by Adam Bien on June 10, 2011 at 07:41 PM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
...the last 150 posts
...the last 10 comments
License