我想将我的项目打包在一个可执行的JAR中进行分发。

如何使Maven项目将所有依赖JAR打包到输出JAR中?


当前回答

将所有依赖项嵌入项目的JAR文件本身可能不是一个好主意。

我明白这一点(易于部署/使用),但这取决于您的项目的用例(可能还有其他选择(见下文))。

如果您完全独立使用,为什么不呢?

但是,如果您在其他上下文中使用项目(例如在web应用程序中,或放置在其他JAR所在的文件夹中),则类路径中可能有JAR副本(文件夹中的副本,JAR文件中的副本)。也许不是出价交易,但我通常避免这样做。

一个很好的选择:

将应用程序部署为ZIP或WAR文件:归档文件包含项目的JAR文件和所有依赖的JAR文件;使用动态类加载器机制(请参阅Spring Framework,或者您可以自己轻松完成)来拥有项目的单个入口点(要启动的单个类-请参阅另一个答案中的Manifest机制),它将(动态)向当前类路径添加所有其他需要的JAR文件。

像这样,最后只需要一个清单和一个“特殊的动态类加载器main”,您就可以开始您的项目:

java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass

其他回答

您可以使用依赖插件在包阶段之前在单独的目录中生成所有依赖项,然后将其包含在清单的类路径中:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>theMainClass</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

或者,使用${project.build.directory}/classes/lib作为OutputDirectory将所有JAR文件集成到主JAR文件中,但随后需要添加自定义类加载代码来加载JAR文件。

对于任何想要从über JAR文件中排除特定依赖项的人来说,这是一个适合我的解决方案:

<project...>
    <dependencies>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.11</artifactId>
            <version>1.6.1</version>
            <scope>provided</scope> <!--  <=============  -->
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>...</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

它不是mvn程序集插件的配置,而是依赖项的属性。

您可以使用maven依赖插件,但问题是如何创建可执行JAR文件。要做到这一点,需要对Matthew Franglen的响应进行以下修改(顺便说一下,从干净的目标开始时,使用依赖插件需要更长的时间来构建):

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>fully.qualified.MainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>unpack-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>unpack-dependencies</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
    <resources>
        <resource>
            <directory>${basedir}/target/dependency</directory>
        </resource>
    </resources>
</build>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.4.1</version>
            <configuration>
                <!-- get all project dependencies -->
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <!-- bind to the packaging phase -->
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

我长期使用Maven汇编插件,但我找不到解决“已添加,跳过”问题的方法。现在,我正在使用另一个插件——onejar maven插件。下面是一个示例(mvn包构建JAR文件):

<plugin>
    <groupId>org.dstovall</groupId>
    <artifactId>onejar-maven-plugin</artifactId>
    <version>1.3.0</version>
    <executions>
        <execution>
            <configuration>
                <mainClass>com.company.MainClass</mainClass>
            </configuration>
            <goals>
                <goal>one-jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

您需要为该插件添加存储库:

<pluginRepositories>
    <pluginRepository>
        <id>onejar-maven-plugin.googlecode.com</id>
        <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
    </pluginRepository>
</pluginRepositories>