Maven - 在 jar 中包含依赖库而不解包依赖项?

Posted

技术标签:

【中文标题】Maven - 在 jar 中包含依赖库而不解包依赖项?【英文标题】:Maven - Include dependent libs in jar without unpacking dependencies? 【发布时间】:2010-12-17 23:52:18 【问题描述】:

我们正在尝试构建一个包含 解压 依赖 jar 的客户端 jar。清单应该有 class-path 依赖 jar 的条目。下面的 sn-p 有效,但罐子已解包 - 我们如何阻止罐子被解包?

       <plugin>
            <artifactId>maven-assembly-plugin</artifactId>

            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>

                <archive>
                  <manifest>
                    <addClasspath>true</addClasspath>
                  </manifest>
                </archive>
            </configuration>

            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

【问题讨论】:

【参考方案1】:

确实,使用jar-with-dependencies 组装会导致maven 解压缩所有依赖项,因为$assembly.dependencySets.dependency.unpack 在相应的组装描述符中设置为true

一个简单的解决方法是提供类似于jar-with-dependencies.xml 的程序集描述符并将$assembly.dependencySets.dependency.unpack 修改为false,如下所示:

编辑:由于未知原因,使用&lt;unpack&gt;false&lt;/unpack&gt; 时的行为并不完全相同,似乎有必要将&lt;outputDirectory&gt;/&lt;/outputDirectory&gt; 添加到文件集中,否则您不会得到预期的结果.

<assembly>
  <id>uberjar</id>
  <formats>
    <format>jar</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <dependencySets>
    <dependencySet>
      <unpack>false</unpack>
      <scope>runtime</scope>
    </dependencySet>
  </dependencySets>
  <fileSets>
    <fileSet>
      <directory>$project.build.outputDirectory</directory>
      <outputDirectory>/</outputDirectory>
    </fileSet>
  </fileSets>
</assembly>

【讨论】:

我还要添加&lt;dependencySets&gt;&lt;dependencySet&gt;&lt;useProjectArtifact&gt;false&lt;/useProjectArtifact&gt;&lt;/dependencySet&gt;&lt;/dependencySets&gt;【参考方案2】:

您可以将依赖项作为 jar 文件添加到您的 jar 中:

assembly-descriptor.xml

<assembly>
    <id>uberjar</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <unpack>false</unpack>
            <scope>runtime</scope>
            <useProjectArtifact>false</useProjectArtifact>
        </dependencySet>
    </dependencySets>
    <fileSets>
        <fileSet>
            <directory>$project.build.outputDirectory</directory>
            <outputDirectory>.</outputDirectory>
        </fileSet>
    </fileSets>
</assembly>

pom.xml

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.6</version>
    <executions>
        <execution>
            <id>make-uberjar</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
            <configuration>
                <descriptor>src/main/assemble/assembly-descriptor.xml</descriptor>
            </configuration>
        </execution>
    </executions>
</plugin>

但很遗憾,您不能在manifest.mf 中使用Class-Path 标头,请参阅Adding Classes to the JAR File's Classpath:

注意:Class-Path 标头指向本地网络上的类或 JAR 文件,而不是 JAR 文件中的 JAR 文件或可通过 Internet 协议访问的类。要将 JAR 文件中的 JAR 文件中的类加载到类路径中,您必须编写自定义代码来加载这些类。例如,如果MyJar.jar 包含另一个名为MyUtils.jar 的JAR 文件,则不能使用MyJar.jar's 清单中的Class-Path 标头将MyUtils.jar 中的类加载到类路径中。

【讨论】:

【参考方案3】:

Pascal Thivent 提出的解决方案为 Maven 程序集插件定义了一个新程序集。 Maven 程序集插件提供默认程序集,它们是“bin”、“jar-with-dependencies”、“project”和“src”,可生成各种预定义的包。

必须在新的 xml 文件中定义新的程序集,大部分时间位于 src/assemble.然后它将被加载而不是预定义的,这样:

<plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-assembly-plugin</artifactId>
      <version>2.2-beta-5</version>
      <configuration>

          <!-- disabled predefined assembly -->
          <!--
          <descriptorRefs>
             <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
          -->

          <descriptors>
             <descriptor>src/assemble/myAssembly.xml</descriptor>
          </descriptors>
      </configuration>
</plugin>

【讨论】:

以上是关于Maven - 在 jar 中包含依赖库而不解包依赖项?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 maven jar 构建过程中包含外部 jar?

使用 Maven 在可执行 JAR 中包含签名库

在打包的 JAR 中包含本地依赖项 [重复]

如何在使用 maven 构建的战争中包含系统依赖项

通过 maven-assembly-plugin 打包在 jar 中包含 spring xml

如何在 Maven 项目中包含本地 jar 文件 [重复]