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

发布于 2024-07-25 03:40:03 字数 540 浏览 9 评论 0 原文

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

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

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

我尝试构建 Jackrabbit 的 OCM 模块。 由于一些非常“聪明”的原因,没有可下载的独立版本 版本。
于是我用Maven构建了Jackrabbit(Jackrabbit的源码包包括 OCM),并获得与 apache 存储库。 该 jar 包含必要的依赖项,对我来说无用

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

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

你如我软肋 2024-08-01 03:40:03

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

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

jar-with-dependencies 由程序集插件预定义,并将在最终包中包含所有依赖项(请参阅文档< a href="http://maven.apache.org/plugins/maven-assemble-plugin/usage.html" rel="nofollow noreferrer">此处)。

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

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:

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

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

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

⒈起吃苦の倖褔 2024-08-01 03:40:03

使用 Maven Shade 插件

...但要小心陷阱(类似于我的答案中进一步描述的问题),它有 此处解释了一种解决方法

另外,对 Shade 插件配置要格外小心。 我有一次不小心使用了双 标签,变压器根本不适用,而且插件也冒昧地没有警告我。

不要使用 Maven Assembly 插件

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

Use the Maven Shade plugin

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

Don't use the Maven Assembly plugin

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

梦幻的心爱 2024-08-01 03:40:03

您可能会对appassembler 插件有一些运气。 如果做不到这一点,请查看程序集插件。 这更灵活,但级别较低。 如果您使用的是程序集插件,则可以在 maven:有用的权威指南

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 guide to be useful.

自由如风 2024-08-01 03:40:03

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

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

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

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.xml file. Simply run:

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.

电影里的梦 2024-08-01 03:40:03

更改 pom.xml 文件并使用 指令。 类似的示例可以在此处< /a> 这样您就可以根据您的情况进行调整。

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

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


以下是上述 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>

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

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

<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>
oО清风挽发oО 2024-08-01 03:40:03

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

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

I believe the Maven Shade Plugin will 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.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文