Maven - Include dependent libs in jar without unpacking dependencies?

大憨熊 提交于 2019-11-30 00:31:42

问题


We're trying to build a client jar that includes unpacked dependent jar's. And the manifest should have class-path entries to the dependent jars. The snippet below works but the jars are unpacked - how can we stop the jars from being unpacked?

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


Indeed, assembling using jar-with-dependencies causes maven to unpack all the dependencies as ${assembly.dependencySets.dependency.unpack} is set to true in the corresponding assembly descriptor.

A simple fix would be to provide an assembly descriptor similar to the jar-with-dependencies.xml and modify ${assembly.dependencySets.dependency.unpack} to false, like this:

EDIT: For an unknown reason, the behavior when using <unpack>false</unpack> is not exactly the same and it seems necessary to add <outputDirectory>/</outputDirectory> to the fileSet or you don't get the expected result.

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



回答2:


You can add your dependencies as jar files to your 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>

But unfortunately you can't use the Class-Path header in manifest.mf, see Adding Classes to the JAR File's Classpath:

Note: The Class-Path header points to classes or JAR files on the local network, not JAR files within the JAR file or classes accessible over Internet protocols. To load classes in JAR files within a JAR file into the class path, you must write custom code to load those classes. For example, if MyJar.jar contains another JAR file called MyUtils.jar, you cannot use the Class-Path header in MyJar.jar's manifest to load classes in MyUtils.jar into the class path.




回答3:


The solution proposed by Pascal Thivent defines a new assembly for the Maven assembly plugin. The Maven assembly plugin offers defaults assemblies which are 'bin', 'jar-with-dependencies', 'project' and 'src' producing various predefined bundles.

A new assembly has to be defined in a new xml file, most of the time located in src/assemble. Then it will be loaded instead of the predefined one, this way:

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


来源:https://stackoverflow.com/questions/1757947/maven-include-dependent-libs-in-jar-without-unpacking-dependencies

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!