4

I've used Maven to build my command line application. Now I'm going to distribute it as a jar file, and I need to handle the app's dependencies.

I don't want to include all dependencies in the jar file as described here.

The environment where my app will be run has Maven. I'd like Maven to run my jar looking at file META-INF/groupId/artifactId/pom.xml inside the package so it knows what the dependencies are and can find them in the repository.

Any ideas ?

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
Leonel
  • 28,541
  • 26
  • 76
  • 103

2 Answers2

6

Include a main class in the jar that 1) extracts the pom to a temporary file, and 2) launches a new maven process using this file with the -f parameter and the goals dependency:resolve and dependency:build-classpath

like this:

mvn -f /temp/tempfile.xml dependency:resolve dependency:build-classpath -DoutputFile=/temp/classpath.txt

then 3) reads the newly created classpath file and 4) launches a new java process using the new classpath file

java -cp yourjar.jar;<created classpath>

Your pom.xml will have to include all required repository information, of course

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • 2
    Great! Works for me with `-Dmdep.outputFile=...` (see UserProperty: http://maven.apache.org/plugins/maven-dependency-plugin/build-classpath-mojo.html#outputFile) – Martín Schonaker Oct 30 '12 at 18:11
  • Option `-Dmdep.outputFile=...` had worked well, but only in `powershell` I was able to copy entire content for command `java -cp yourjar.jar;` and `powershell` had behaved differently. So wasn't succeeded. – Dev Anand Sadasivam Apr 25 '18 at 11:07
0

We can use, maven-jar-plugin instead, why because the classpath generated is not getting accommodated while copy paste with java command in command-line.

mvn -f /temp/tempfile.xml dependency:resolve dependency:build-classpath -DmdepoutputFile=/temp/classpath.txt

So wasn't able to succeed copying classpath.txt for the command,

java -cp yourjar.jar;<created classpath>

Mine is spring-boot application hence I have the following line with BOOT-INF/lib. For you it can be WEB-INF/lib in case of .war file or just lib/ in case of ant build based projects.

<classpathLayoutType>custom</classpathLayoutType>
<customClasspathLayout>BOOT-INF/lib/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>

BOOT-INF, comes up by spring-boot:repackage maven command and with the use of plugin,-spring-boot-maven-plugin that I have not Included here.

Please find maven-jar-plugin config here.

     <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
            <archive>
                <manifest>
                    <addClasspath>true</addClasspath>
                    <mainClass>com.pakage.SampleApplication</mainClass>
                    <!--<classpathPrefix>lib/</classpathPrefix>-->                          
                    <classpathLayoutType>custom</classpathLayoutType>
                    <customClasspathLayout>BOOT-INF/lib/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>
                    <!--<customClasspathLayout>BOOT-INF/lib/$${artifact.groupIdPath}/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>-->                      
                </manifest>
            </archive>
        </configuration>
    </plugin>
Dev Anand Sadasivam
  • 699
  • 7
  • 21
  • 49
  • It is not needed as because `WEB-INF/lib` `BOOT-INF/lib` are detected by default, if you have different setting, say you have libraries placed somewhere inside or somewhere else, then it helps. Accordingly you can configure it. – Dev Anand Sadasivam Apr 27 '18 at 08:26
  • Actually I have similar problem as discussed here,- [Loading one configuration file in lib jar](https://stackoverflow.com/questions/6823597/java-loading-resources-class-class-getresource-vs-classname-class-getresource) with regards to that I am packing and exploring `MANIFEST.MF` configuration. – Dev Anand Sadasivam Apr 27 '18 at 09:46
  • You need to add couple of dependencies first in order to work with `maven-jar-plugin`, those are `org.codehaus.plexus - plexus-utils` and `commons-lang` – Dev Anand Sadasivam Apr 27 '18 at 09:55
  • https://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven this feed helps in building jar file with dependencies, maven command needs to used is `mvn clean compile assembly:single`, that you can find it as part of the feed. – Dev Anand Sadasivam Mar 03 '21 at 11:48