Only create executable jar-with-dependencies in Maven

允我心安 提交于 2020-01-09 19:39:35

问题


In my pom.xml I use the maven-assembly-plugin to create an executable jar-with-dependencies when running "mvn clean install". Now it first creates the non-executable "name-version.jar" and after that the "name-version-jar-with-dependencies.jar".

Can I configure the pom.xml somehow, so that it doesn't create the non-executable JAR file?

At the moment I use <appendAssemblyId>false</appendAssemblyId> so it just overwrites the first file...

Also I get several "... already added, skipping" messages. Can I somehow prevent them?

This is the maven-assembly-plugin definition in my pom.xml:

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2-beta-5</version>
    <configuration>
        <appendAssemblyId>false</appendAssemblyId>
        <archive>
            <manifest>
                <mainClass>my.main.class</mainClass>
            </manifest>
        </archive>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
    </configuration>
    <executions>
        <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>

回答1:


I got it to work using the maven-jar-plugin and the single goal of maven-assembly-plugin like this

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
            <configuration>
                <finalName>finalName</finalName>
                <archive>
                    <manifest>
                        <mainClass>
                            mainClass
                        </mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </execution>
    </executions>
</plugin>

Anyway the most important thing is to tell maven not to generate the default jar using this configuration of the maven-jar-plugin

<plugin>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.0.2</version>
    <executions>
        <execution>
            <id>default-jar</id>
            <phase>none</phase>
        </execution>
    </executions>
</plugin>



回答2:


I think I've figured out how to do this. You have to leave the jar, otherwise you'll lose the compiler and resource copying, and everything else that goes along with building a jar that you need.

My solution involves essentially tricking maven, so I guess the thing to beware of is that it's very possible that in future releases this won't work...

<build>
    <defaultGoal>install</defaultGoal>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <finalName>dumpster-diver</finalName>
                <appendAssemblyId>false</appendAssemblyId>
                <archive>
                    <manifest>
                        <mainClass>DumpsterDiver</mainClass>
                    </manifest>
                </archive>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
    <finalName>${project.artifactId}</finalName>
</build>

Note that in the build configuration listed, the finalName of both the maven-assembly-plugin AND the build itself match. Also note the <appendAssemblyId>false</appendAssemblyId>. If you do this, the output filename of the build and of the assembly jar will match exactly. Maven will definitely warn you about this, but will put the jar you want in your target directory AND in your local repository.

Here is the output of 'mvn clean install' on this project, as well as jar -tvf on both the jar in the target directory and in the local repository:

$ mvn clean install
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building dumpster-diver
[INFO]    task-segment: [clean, install]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean {execution: default-clean}]
[INFO] Deleting directory <currentDirectory>/target
[INFO] [resources:resources {execution: default-resources}]
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Compiling 1 source file to <currentDirectory>/target/classes
[INFO] [resources:testResources {execution: default-testResources}]
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory <currentDirectory>/src/test/resources
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] No sources to compile
[INFO] [surefire:test {execution: default-test}]
[INFO] No tests to run.
[INFO] [jar:jar {execution: default-jar}]
[INFO] Building jar: <currentDirectory>/target/dumpster-diver.jar
[INFO] [assembly:single {execution: default}]
[INFO] Processing DependencySet (output=)
[WARNING] Artifact: <groupId>:dumpster-diver:jar:0.1.0-SNAPSHOT references the same file as the assembly destination file. Moving it to a temporary location for inclusion.
[INFO] Building jar: <currentDirectory>/target/dumpster-diver.jar
[WARNING] Configuration options: 'appendAssemblyId' is set to false, and 'classifier' is missing.
Instead of attaching the assembly file: <currentDirectory>/target/dumpster-diver.jar, it will become the file for main project artifact.
NOTE: If multiple descriptors or descriptor-formats are provided for this project, the value of this file will be non-deterministic!
[WARNING] Replacing pre-existing project main-artifact file: <currentDirectory>/target/archive-tmp/dumpster-diver.jar
with assembly file: <currentDirectory>/target/dumpster-diver.jar
[INFO] [install:install {execution: default-install}]
[INFO] Installing <currentDirectory>/target/dumpster-diver.jar to /opt/m2repo/<groupId>/dumpster-diver/0.1.0-SNAPSHOT/dumpster-diver-0.1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Thu Aug 18 13:08:56 EDT 2011
[INFO] Final Memory: 22M/618M
[INFO] ------------------------------------------------------------------------
krohr@krohr-Latitude-E6500:<currentDirectory>
$ jar -tvf ./target/dumpster-diver.jar | grep -i "dump"
  6831 Thu Aug 18 13:08:54 EDT 2011 DumpsterDiver.class
  6831 Thu Aug 18 13:08:54 EDT 2011 DumpsterDiver.class
     0 Thu Aug 18 13:08:56 EDT 2011 META-INF/maven/<groupId>/dumpster-diver/
  2580 Thu Aug 18 13:01:46 EDT 2011 META-INF/maven/<groupId>/dumpster-diver/pom.xml
       126 Thu Aug 18 13:08:54 EDT 2011 META-INF/maven/<groupId>/dumpster-diver/pom.properties
krohr@krohr-Latitude-E6500:<currentDirectory>
$ jar -tvf /opt/m2repo/<groupId>/dumpster-diver/0.1.0-SNAPSHOT/dumpster-diver-0.1.0-SNAPSHOT.jar | grep -i "dump"
  6831 Thu Aug 18 13:08:54 EDT 2011 DumpsterDiver.class
  6831 Thu Aug 18 13:08:54 EDT 2011 DumpsterDiver.class
     0 Thu Aug 18 13:08:56 EDT 2011 META-INF/maven/<groupId>/dumpster-diver/
  2580 Thu Aug 18 13:01:46 EDT 2011 META-INF/maven/<groupId>/dumpster-diver/pom.xml
   126 Thu Aug 18 13:08:54 EDT 2011 META-INF/maven/<groupId>/dumpster-diver/pom.properties



回答3:


You could try setting to pom. This will prevent the creation of the default jar.

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/xsd/maven-4.0.0.xsd">
  ...
  <packaging>pom</packaging>
  ...
</project>



回答4:


Maybe im missing something about your question but the following code makes me a single executable jar: Is this what you are looking for?

              <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-jar-plugin</artifactId>
              <version>2.3.1</version>
              <configuration>
                    <archive>
                          <manifest>
                              <addClasspath>true</addClasspath>
                                <mainClass>some.main.class</mainClass>
                          </manifest>
                    </archive>
                    <finalName>Proj-${project.version}</finalName>
                    <outputDirectory>target</outputDirectory>
              </configuration>
        </plugin>



回答5:


You can use this build below and compile with this command :

mvn clean compile assembly:single

<build>
    <plugins>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.1.0</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>youMainClass</mainClass>
                        </manifest>
                    </archive>

                    <finalName>${artifactId}</finalName>
                    <appendAssemblyId>false</appendAssemblyId>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
        </plugin>
    </plugins>
</build>



回答6:


If it helps, I was able to resolve this as follows, which gets rid of all warnings and replaces the uber jar in the same location as the original output jar, more like what the spring boot uber jar plugin does without the spring boot dependencies.

Key aspects:

  • appendAssemblyId = true
  • attach = false
  • antrun renames files
  • plugin execution order is defined by order in POM file
<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <appendAssemblyId>true</appendAssemblyId>
        <attach>false</attach>
        <archive>
          <manifest>
            <mainClass>foo.bar.Baz</mainClass>
          </manifest>
        </archive>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </execution>
  </executions>
</plugin>
<plugin>
  <artifactId>maven-antrun-plugin</artifactId>
  <executions>
    <execution>
      <id>rename-jar-with-dependencies</id>
      <phase>package</phase>
      <goals>
        <goal>run</goal>
      </goals>
      <configuration>
        <target>
          <move file="${project.build.directory}/${project.build.finalName}.jar"
            tofile="${project.build.directory}/${project.build.finalName}.jar.original" />
          <move file="${project.build.directory}/${project.build.finalName}-jar-with-dependencies.jar"
            tofile="${project.build.directory}/${project.build.finalName}.jar" />
        </target>
      </configuration>
    </execution>
  </executions>
</plugin>


来源:https://stackoverflow.com/questions/5016467/only-create-executable-jar-with-dependencies-in-maven

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!