Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: How do I build standalone distributions of Maven-based projects?

I often encounter distributions of Java applications or libraries which use Maven as their build tool.

Some of them, sadly, don't provide standalone (or redistributable) jars.

Is it possible to build Maven-based applications in such a way, that the build result contains all dependencies and can be redistributed to work out-of-the box?

I tried to build Jackrabbit's OCM module. For some very "intelligent" reasons there is no downloadable standalone version.
So I built Jackrabbit with Maven (the source package of Jackrabbit includes OCM), and got the same jar as found in the apache repository. The jar doesn't contain necessary dependencies and is useless to me.

like image 658
ivan_ivanovich_ivanoff Avatar asked Jun 18 '09 22:06

ivan_ivanovich_ivanoff


People also ask

What is the way to compile Maven application?

To build a Maven project via the command line, you use the mvn command from the command line. The command must be executed in the directory which contains the relevant pom file. You pass the build life cycle, phase or goal as parameter to this command.


2 Answers

As Dominic said, using the assembly plugin will do the trick. You would usually configure it inside your own project's POM to gather and package all required dependencies:

  ...
  <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
    </configuration>
  </plugin>
  ...

jar-with-dependencies is predefined by the assembly plugin and will include all dependencies in the final package (see the documentation here).

If you don't want to use Maven for your own project, you will need to modify the libraries' POMs and repackage them yourself (download the sources, add the above snippet to pom.xml and run mvn package). Beware of duplicate or incompatible transitive dependencies if you use multiple libraries. exclusions might help in that case (see documentation here).

like image 51
Nils Wloka Avatar answered Oct 14 '22 09:10

Nils Wloka


Use the Maven Shade plugin

...but be careful of the gotchas (similar to the one described further down my answer), which has got a workaround explained here.

Also, be ultra careful with the Shade plugin config. I accidentally used double <configuration> tags once, and the transformers didn't apply at all, and the plugin also took the liberty of not warning me.

Don't use the Maven Assembly plugin

assembly:single will unpack your dependency JARs as-is, and this could not be what you want. E.g. stuff like META-INF/spring.schemas will be overridden with the last Spring dependency JAR that's evaluated, and as such your XSDs won't be found (apart from those in the last JAR, of course). Which is why systems like Alfresco made their AMP plugin which bundles dependencies inside lib/ inside the AMP you're building. The latter raises dependency management issues, though.

like image 39
opyate Avatar answered Oct 14 '22 11:10

opyate