如何生成具有所有 Maven 依赖项的可执行 jar 文件?
How to produce an executable jar file with all maven dependencies?
我有一个 Maven 项目,我想生成包含所有依赖项的 jar 文件。
我使用 package shade plugin 和命令 mvn package
来生成 jar 文件。
但是,生成的 jar 文件不考虑 pom.xml 的任何依赖项。生成的 jar 文件不断给我异常:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Level
这里是pom.xml的内容:
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>myProject-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>myProject-parser</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
<version>${picoli.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${shade.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.13.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.1</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>client</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${shade.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>myProject-client-${project.version}</finalName>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>myProject.package.main</mainClass>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
</transformers>
<filters>
<!-- This is necessary to avoid a java.lang.SecurityException -->
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<!-- Jar file entry point -->
<mainClass>myProject.package.main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
我的错误在哪里?
它甚至不考虑 <mainClass>myProject.package.main</mainClass>
作为主要 class 当我 运行 jar 我必须指定 class 名称:
java -cp myApp.jar myProject.package.main
我查看了大部分问题,但没有解决我的问题。
org.apache.log4j 的依赖项中没有 groupId,您有:org.apache.logging.log4j 但它与:org.apache.log4j[=10 不同=]
首先,有两个插件可以用来创建fat jar:maven-shade-plugin和maven-assembly-plugin.
它们之间的主要区别在于 maven-assembly 只是构建一个包含所有依赖项的 jar,而 maven-shade 也在内部重新定位这些依赖项,这样,如果另一个项目依赖于您的 jar,您就不会冒险在依赖项上有冲突。
如果您不希望将此工件用作其他项目的依赖项,则可以为其使用 maven-assembly-plugin。这是一个如何使用它的例子:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<finalName>${project.artifactId}</finalName>
<archive>
<manifest>
<mainClass>myProject.package.main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
如果你真的需要隐藏你的依赖关系,尝试用这个修改插件的清单配置,至少它应该解决你在识别主要问题时遇到的问题class:
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>myProject.package.main</Main-Class>
<X-Compile-Source-JDK>${maven.compiler.source}</X-Compile-Source-JDK>
<X-Compile-Target-JDK>${maven.compiler.target}</X-Compile-Target-JDK>
</manifestEntries>
</transformer>
我有一个 Maven 项目,我想生成包含所有依赖项的 jar 文件。
我使用 package shade plugin 和命令 mvn package
来生成 jar 文件。
但是,生成的 jar 文件不考虑 pom.xml 的任何依赖项。生成的 jar 文件不断给我异常:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Level
这里是pom.xml的内容:
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>myProject-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>myProject-parser</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
<version>${picoli.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${shade.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.13.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.1</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>client</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${shade.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>myProject-client-${project.version}</finalName>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>myProject.package.main</mainClass>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
</transformers>
<filters>
<!-- This is necessary to avoid a java.lang.SecurityException -->
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<!-- Jar file entry point -->
<mainClass>myProject.package.main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
我的错误在哪里?
它甚至不考虑 <mainClass>myProject.package.main</mainClass>
作为主要 class 当我 运行 jar 我必须指定 class 名称:
java -cp myApp.jar myProject.package.main
我查看了大部分问题,但没有解决我的问题。
org.apache.log4j 的依赖项中没有 groupId,您有:org.apache.logging.log4j 但它与:org.apache.log4j[=10 不同=]
首先,有两个插件可以用来创建fat jar:maven-shade-plugin和maven-assembly-plugin.
它们之间的主要区别在于 maven-assembly 只是构建一个包含所有依赖项的 jar,而 maven-shade 也在内部重新定位这些依赖项,这样,如果另一个项目依赖于您的 jar,您就不会冒险在依赖项上有冲突。
如果您不希望将此工件用作其他项目的依赖项,则可以为其使用 maven-assembly-plugin。这是一个如何使用它的例子:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<finalName>${project.artifactId}</finalName>
<archive>
<manifest>
<mainClass>myProject.package.main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
如果你真的需要隐藏你的依赖关系,尝试用这个修改插件的清单配置,至少它应该解决你在识别主要问题时遇到的问题class:
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>myProject.package.main</Main-Class>
<X-Compile-Source-JDK>${maven.compiler.source}</X-Compile-Source-JDK>
<X-Compile-Target-JDK>${maven.compiler.target}</X-Compile-Target-JDK>
</manifestEntries>
</transformer>