Java:如何构建基于 Maven 的项目的独立发行版?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1015520/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 14:48:34  来源:igfitidea点击:

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

javamaven-2build-processbuild-automation

提问by ivan_ivanovich_ivanoff

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

我经常遇到使用 Maven 作为构建工具的 Java 应用程序或库的发行版。

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

遗憾的是,其中一些不提供独立的(或可重新分发的)jar。

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

是否有可能以这种方式构建基于 Maven 的应用程序,即构建结果包含所有依赖项并且可以重新分发以开箱即用?

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

我试图构建 Hymanrabbit 的 OCM 模块。由于某些非常“智能”的原因,没有可下载的独立版本。
所以我用 Maven 构建了 Hymanrabbit(Hymanrabbit 的源包包含 OCM),并得到了在apache 存储库中找到的相同 jar 。jar包含必要的依赖项,对我来说没用

回答by Nils Wloka

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:

正如多米尼克所说,使用程序集插件可以解决问题。您通常会在自己项目的 POM 中配置它以收集和打包所有必需的依赖项:

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

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

jar-with-dependencies由程序集插件预定义,并将在最终包中包含所有依赖项(请参阅此处的文档 )。

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. exclusionsmight help in that case (see documentation here).

如果您不想在自己的项目中使用 Maven,则需要修改库的 POM 并自行重新打包(下载源代码,将上述代码段添加到 pom.xml 并运行mvn package)。如果您使用多个库,请注意重复或不兼容的传递依赖项。exclusions在这种情况下可能会有所帮助(请参阅此处的文档)。

回答by opyate

Use the Maven Shade plugin

使用 Maven 阴影插件

...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.

此外,对 Shade 插件配置要格外小心。一次不小心用了双<configuration>标签,transformers根本不适用,插件也冒昧不警告我。

Don't use the Maven Assembly plugin

不要使用 Maven 程序集插件

assembly:singlewill unpack your dependency JARs as-is, and this could not be what you want. E.g. stuff like META-INF/spring.schemaswill 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.

assembly:single将按原样解压缩您的依赖 JAR,这可能不是您想要的。例如,像这样的东西META-INF/spring.schemas将被评估的最后一个 Spring 依赖 JAR 覆盖,因此不会找到您的 XSD(当然,除了最后一个 JAR 中的那些)。这就是像 Alfresco 这样的系统制作他们的 AMP 插件的原因,该插件将lib/您正在构建的 AMP 内部的依赖项捆绑在一起。不过,后者引发了依赖性管理问题。

回答by Dominic Mitchell

You may have some luck with the appassembler plugin. Failing that, take a look at the assembly plugin. That's more flexible, but lower level. If you're using the assembly plugin, you may find the chapter on it in maven: the definitive guideto be useful.

您可能对appassembler 插件有一些运气。如果没有,请查看程序集插件。这更灵活,但级别较低。如果您使用的是程序集插件,您可能会在maven: the definition guide 中找到有关它的章节,很有用。

回答by reidarok

As a couple of the posters said, the assembly plugin is a good way of creating a complete jar file, with all project dependencies. However, you don't actually have to modify the pom.xmlfile. Simply run:

正如一些海报所说,程序集插件是创建完整 jar 文件的好方法,其中包含所有项目依赖项。但是,您实际上不必修改pom.xml文件。只需运行:

mvn assembly:single -DdescriptorId=jar-with-dependencies

... in order to create a jar file. If you want to do anything more advanced, you should probably modify pom.xml, and create a custom assembly descriptor.

...为了创建一个jar文件。如果您想做任何更高级的事情,您可能应该修改 pom.xml,并创建一个自定义程序集描述符。

回答by Brian Matthews

I believe the Maven Shade Pluginwill satisfy your needs. I use it when I am building command line interface tools to create an Uber JAR including my classes and along with the classes from all my dependencies.

我相信Maven Shade Plugin会满足您的需求。我在构建命令行界面工具以创建 Uber JAR 时使用它,其中包括我的类以及所有依赖项中的类。

Its very easy to use and I think this exampleis self-explanatory.

它非常易于使用,我认为这个例子是不言自明的。

回答by Jorge Ferreira

Change the pom.xmlfile and use the <Embed-Dependency>directive. A similar example can be found hereso you can adapt it to your scenario.

更改pom.xml文件并使用<Embed-Dependency>指令。可以在此处找到类似的示例以便您可以根据自己的情况进行调整。

<Embed-Dependency>*;scope=!test;inline=true</Embed-Dependency>

I think this should do the trick.

我认为这应该可以解决问题。



Here is the example at the above URL that seems to give timeout.

这是上面 URL 中似乎给出超时的示例。

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>br.gov.lexml</groupId>
    <artifactId>toolkit</artifactId>
    <packaging>bundle</packaging>
    <version>3.0</version>
    <parent>
        <artifactId>lexml</artifactId>
        <groupId>br.gov.lexml</groupId>
        <version>1.0</version>
    </parent>
    <build>
        <finalName>Lexml_Toolkit-2.0</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <!--_include>src/toolkit/resources/META-INF/MANIFEST.MF</_include-->

                        <Export-Package>*;-split-package:=merge-last</Export-Package>
                        <Bundle-Activator>br.gov.lexml.borda.Toolkit</Bundle-Activator>
                        <Bundle-Name>Toolkit</Bundle-Name>
                        <Private-Package />
                        <Embed-Dependency>*;scope=!test;inline=true</Embed-Dependency>
                        <Bundle-ClassPath>.,{maven-dependencies}</Bundle-ClassPath>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.apache.xmlbeans</groupId>
            <artifactId>xmlbeans</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlbeans</groupId>
            <artifactId>xmlbeans-xmlpublic</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.15</version>
        </dependency>
        <dependency>
            <groupId>br.gov.lexmlbeans</groupId>
            <artifactId>lexmlbeans</artifactId>
            <version>3.0</version>
        </dependency>
    </dependencies>
</project>