我能够得到 Rich Seller 方法的稍微修改的版本,避免了 cmets 中提到的 Error assembling JAR: Unable to read manifest file (line too long) 问题。
我想通过 .jar 文件的清单类路径中引用的 dependency-maven-plugin 复制所有依赖项。我无法使用 Maven Jar 插件的 <addClasspath>true</addClasspath> 选项,因为它在我的 Jar 类路径中放了太多东西(我只是复制了一些依赖项)。
这是我如何让它工作的。
首先我使用 Maven 依赖插件进行复制,同时构建一个类路径变量。使用<outputProperty> 我把它放在一个属性而不是一个文件中:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>copy-dependencies</goal>
<goal>build-classpath</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<!-- These properties are for build-classpath. It creates a classpath for the copied
dependencies and puts it in the ${distro.classpath} property. The jar Class-Path
uses spaces as separators. Unfortunately <pathSeparator> configuration property
does not work with a space as value, so the pathSeparator is set to a character
here and this is then replaced later using the regex-property plugin. -->
<prefix>lib</prefix>
<outputProperty>distro.classpath</outputProperty>
<pathSeparator>:</pathSeparator>
</configuration>
</execution>
</executions>
</plugin>
Jar Manifest Class-Path 的语法使用 空格 作为分隔符。虽然依赖插件有一个<pathSeparator> 属性,但不幸的是,如果它是一个空格,它会忽略该值。所以我只是将它硬编码为某个值,然后使用 build-helper-maven-plugin 将其替换为我需要的空间:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<!-- Here the value of property for the jar the Class-Path is replaced to have a space
as separator. Unfortunately <replacement> does not work if a single space if specified
so this uses the surrounding .jar and lib to provide some content. -->
<name>distro.classpath.replaced</name>
<value>${distro.classpath}</value>
<regex>[.]jar[:]lib</regex>
<replacement>.jar lib</replacement>
</configuration>
</execution>
</executions>
</plugin>
在这里,<replacement> 值如果只是一个空格也不起作用,所以我用它周围存在的文本将它包围起来。
最后我可以使用 Maven Jar Plugin 来获取被替换为空格的属性作为分隔符。因为我在 maven 定义中传递了类路径的值(而不是从过滤的文件中提取),所以 Manifest 文件的行长约束会自动处理,不会出现“行太长”的问题:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>org.acme.Main</mainClass>
</manifest>
<manifestEntries>
<!-- Include the computed classpath with all copied dependencies in the jar here -->
<Class-Path>${distro.classpath.replaced}</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>