【问题标题】:Java: How do I build standalone distributions of Maven-based projects?Java:如何构建基于 Maven 的项目的独立发行版?
【发布时间】:2010-11-04 04:06:00
【问题描述】:

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

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

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

我尝试构建 Jackrabbit 的 OCM 模块。 由于一些非常“智能”的原因,没有可下载的独立 版本。
所以我用 Maven 构建了 Jackrabbit(Jackrabbit 的源包包括 OCM),并得到与 apache repository 中相同的 jar。 jar 不 包含必要的依赖项,对我来说无用。

【问题讨论】:

标签: java maven-2 build-process build-automation


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

    使用 Maven Shade 插件

    ...但要小心陷阱(类似于我的答案后面描述的那个),它有a workaround explained here。

    另外,对 Shade 插件配置要格外小心。我不小心用了双&lt;configuration&gt;标签一次,变形金刚根本不适用,插件还冒昧的不警告我。

    不要使用 Maven Assembly 插件

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

    【讨论】:

      【解决方案3】:

      appassembler plugin 可能会给您带来一些运气。如果做不到这一点,请查看assembly plugin。这更灵活,但级别更低。如果您使用的是组装插件,您可能会发现 maven: the definitive guide 中的相关章节很有用。

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          【解决方案5】:

          更改pom.xml 文件并使用&lt;Embed-Dependency&gt; 指令。可以在here 找到一个类似的示例,以便您可以根据自己的场景进行调整。

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

          【讨论】:

          • 您的链接导致超时。请告诉我在哪里放置指令。我在网上找不到可用的说明。
          • 刚刚将文档 cmets 粘贴在答案中。希望对您有所帮助。
          • 对不起,我对 maven 完全陌生,老实说,我什至不想更深入地了解它。所以,我不知道:1)我是否必须编辑主 pom.xml,或者所需模块之一(我想将其构建为 redist 包),2)Bundle-Activator 似乎是什么与您的项目有关,那么我将如何更改它以使其工作?主要问题是:我通过 SSH 远程做所有事情,所以我尝试的灵活性非常有限。
          • 此解决方案似乎特定于 OSGi
          【解决方案6】:

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

          它非常易于使用,我认为example 是不言自明的。

          【讨论】:

            猜你喜欢
            • 2012-05-26
            • 2011-10-23
            • 1970-01-01
            • 2022-09-28
            • 2010-12-16
            • 2012-03-24
            • 1970-01-01
            • 2017-08-05
            • 1970-01-01
            相关资源
            最近更新 更多