簡體   English   中英

Maven - 如何向 jar 添加任意類路徑條目?

[英]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 元素合並條目

https://issues.apache.org/jira/browse/MJAR-41

我能夠得到 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM