1

We have created a jar(Spring project) which we are including using Maven in another Spring project (war)

we can use this no problem if we include the required dependancies.

If I wanted to ensure the jar contained all it's depenadancies and used them what is the best way to go about this ?

To avoid having to include the dependancies I have tried in using the maven assembly plugin which definately includes the files - but these appear to be ignored as they are still required as dependancies in the consuming project - any suggestions why?

POM detail for assembly plugin

<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.5</source>
                <target>1.5</target>
            </configuration>
        </plugin>
         <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2.1</version>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>

    </configuration>
    <executions>
      <execution>
        <id>make-assembly</id> <!-- this is used for inheritance merges -->
        <phase>package</phase> <!-- bind to the packaging phase -->
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
Shaun Hare
  • 3,771
  • 2
  • 24
  • 36

2 Answers2

1

You can use the maven winstone plugin to create a standalone executable jar with all dependencies included of the war, the jar etc....

Adding

<plugins>
  <plugin>
    <groupId>net.sf.alchim</groupId>
    <artifactId>winstone-maven-plugin</artifactId>
    <version>1.2</version>
    <executions>
      <execution>
        <goals>
          <goal>embed</goal>
        </goals>
        <phase>install</phase>
      </execution>
    </executions>
    <configuration>
      <filename>${project.parent.build.finalName}.jar</filename>
    </configuration>
  </plugin>
  ...
</plugins>

will bundle all modules of your app, wars and jars, and any needed dependencies in a executable jar which includes a servlet engine.

This works really nice to give a single deployable bundle to your Ops team for deploying.

I would advise against creating a jar which contain all dependencies to be used by the war however. You are likely to end up with multiple copies of slightly different versions of the same classes in the class path. Certain libraries are a bit euhhmmm, ..., temperamentfull about this (hibernate and log4j spring to mind).

Maven does a decent job of figuring out which dependencies to take, and if things break mvn dependency:tree make things a lot clearer. You lose this when you create an uber-jar.

If there are good reasons to do this, I would recommend an environment where you can tightly control the classpaths like a full-blown J2EE server or using an OSGi container. However, be careful what you wish for : these are not kittens to be handled without (iron) gloves.

Peter Tillemans
  • 34,983
  • 11
  • 83
  • 114
  • winstone-maven-plugin:1.2:embed (default) --- [INFO] work only for packaging == 'war' I would like to package this as a jar to be able to include it in other code – Shaun Hare Jun 06 '11 at 10:15
  • Thanks Peter. As I am relatively new to this I thought this would be a better way of distributing shared code, take on what you have said and will ensure people add the dependencies to the war – Shaun Hare Jun 06 '11 at 10:25
  • I expanded my answer regarding creating user-jars for the module. I would seriously suggest staying away from there to avoid descending in jar-hell. Maven and other build tools do a great job of dealing with dependencies in a way there are no duplicates on the classpath. ANother solution is to "simply" deploy the jar standalone, separate from the WAR and talk over some kind of RPC which can then be used by other clients too. – Peter Tillemans Jun 06 '11 at 10:28
  • There is also the maven shade plugin. It solves this problem by moving the included classes in another package. See http://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html – Peter Tillemans Jun 06 '11 at 10:32
0

I use the following assembly configuration to create a jar with all runtime dependencies included:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
    <id>runnable</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <unpack>true</unpack>
            <scope>runtime</scope>
        </dependencySet>
    </dependencySets>
    <fileSets>
        <fileSet>
            <directory>${project.build.outputDirectory}</directory>
            <includes>
                <include>*.jar</include>
            </includes>
        </fileSet>
    </fileSets>
</assembly>
Tarlog
  • 10,024
  • 2
  • 43
  • 67