[英]Maven - how can I add an arbitrary classpath entry to a jar?
我有一個不尋常的情況,我需要將任意類路徑條目(指向 jar 文件)添加到可執行 jar 的清單中。 (這是針對 Swing 桌面應用程序的。)
maven-jar-plugin 使用 maven 依賴項為 jar 清單生成“Class-Path”條目,並且似乎沒有任何添加任意條目的方法。
我還查看了使用“-classpath”參數將任意類路徑條目硬編碼到啟動應用程序的批處理文件中,但我不知道如何讓 Maven 將類路徑過濾到批處理文件中。
我發現這個問題有一個簡單的解決方案。 您可以將<Class-Path>
元素添加到<manifestEntries>
元素,並將<addClassPath>true</addClassPath>
為<manifest>
元素。 所以<Class-Path>
元素的值會自動添加到 class-path 中。 例子:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addClasspath>true</addClasspath>
<mainClass>your.main.Class</mainClass>
</manifest>
<manifestEntries>
<Class-Path>../conf/</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
更新:這是將類路徑過濾到自定義清單中的方法。
maven-dependency-plugin 的build-classpath
目標可以配置為將類路徑輸出到屬性格式的文件中(即 classpath=[classpath])。 然后配置過濾器元素以使用生成的類路徑文件,並配置要過濾的資源目錄。
例如:
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>build-classpath</goal>
</goals>
</execution>
</executions>
<configuration>
<outputFilterFile>true</outputFilterFile>
<outputFile>${project.build.directory}/classpath.properties</outputFile>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>
${project.build.outputDirectory}/META-INF/MANIFEST.MF
</manifestFile>
</archive>
</configuration>
</plugin>
</plugins>
<filters>
<filter>${project.build.directory}/classpath.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
然后在 src/main/resources/META-INF/Manifest.MF 中指定以下內容:
Bundle-Version: 4.0.0
...
Classpath: ${classpath};[specify additional entries here]
注意:使用標准窗口路徑分隔符 ( \\
) 進行此處理存在一個錯誤,生成路徑被剝離了分隔符(注意它在 Linux 上工作正常)。 您可以通過在build-classpath
目標的配置中指定<fileSeparator>\\\\\\\\</fileSeparator>
來為 Windows 正確生成build-classpath
。
您可以在jar-plugin的配置中自定義清單。 為此,您需要在 pom.xml 中添加類似的內容。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
...
<configuration>
<archive>
<index>true</index>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<mode>development</mode>
<url>${pom.url}</url>
<key>value</key>
</manifestEntries>
</archive>
</configuration>
...
</plugin>
完整的歸檔器規范提供了很多選項。 有關配置類路徑的選項,請參閱示例頁面。
如果這些都不適合你,你可以定義你自己的 Manifest ,設置包含所需條目的屬性,並使用過濾器用這些屬性填充清單
嘗試像他們在這個錯誤中所做的那樣,即使用 manifestEntries/Class-Path 元素合並條目
我能夠得到 Rich Seller 方法的稍微修改版本,避免了Error assembling JAR: Unable to read manifest file (line too long)
評論中提到的Error assembling JAR: Unable to read manifest file (line too long)
問題。
我想通過 .jar 文件的 Manifest Class-Path 中引用的dependency-maven-plugin
復制所有依賴項。 我無法使用 Maven Jar 插件的<addClasspath>true</addClasspath>
選項,因為它在我的 Jar 類路徑中放置了太多內容(我只是復制了一些依賴項)。
這就是我如何讓它工作的。
首先,我使用 Maven Dependency Plugin 進行復制,同時構建一個類路徑變量。 使用<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 插件來獲取被空格替換為分隔符的屬性。 因為我在 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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.