代码之家  ›  专栏  ›  技术社区  ›  Ken Liu

Maven-如何向jar添加任意类路径条目?

  •  61
  • Ken Liu  · 技术社区  · 15 年前

    我有一个不寻常的情况,需要将任意类路径条目(指向jar文件)添加到可执行jar的清单中(这适用于Swing桌面应用程序。)

    maven jar插件使用maven依赖项为jar清单生成“类路径”条目,并且似乎没有任何添加任意条目的方法。

    我还研究了使用“-classpath”参数将任意类路径条目硬编码到启动应用程序的批处理文件中,但我不知道如何让Maven将类路径过滤到批处理文件中。

    3 回复  |  直到 15 年前
        1
  •  80
  •   Gray droiddeveloper    5 年前

    <Class-Path> 元素到 <manifestEntries> 元素和集合 <addClassPath>true</addClassPath> <manifest> 元素。所以价值 <类路径> 元素将自动添加到类路径。例子:

    <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>
    
        2
  •  18
  •   Rich Seller    15 年前

    maven依赖插件的 build-classpath 可以将目标配置为以属性格式(即classpath=[classpath])将类路径输出到文件。然后配置filters元素以使用生成的类路径文件,并配置要筛选的资源目录。

    例如:

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

    Bundle-Version: 4.0.0
    ...
    Classpath: ${classpath};[specify additional entries here]
    

    注: 使用标准窗口路径分隔符进行此处理时存在错误( \ <fileSeparator>\\\\</fileSeparator>


    您可以在中自定义清单 jar-plugin

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

    全部 archiver specification examples page 有关配置类路径的选项。

    如果这些都不适合你,你可以 define your own Manifest ,设置包含所需条目的属性,并使用 filter

        3
  •  5
  •   Pedro    6 年前

    尝试像在这个bug中那样做,即使用manifestEntries/Class-Path元素合并条目

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

        4
  •  0
  •   David Bosschaert    3 年前

    我能够得到一个稍微修改过的Rich Seller方法,避免了 Error assembling JAR: Unable to read manifest file (line too long) 评论中提到的问题。

    dependency-maven-plugin 在.jar文件的清单类路径中引用。我没法用这个电话 <addClasspath>true</addClasspath> Maven Jar插件的选项,因为它在我的Jar类路径中放了太多东西(我只是复制了一部分依赖项)。

    我是这样做的。

    <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清单的语法 Class-Path 使用 空间 作为分离器。而依赖插件有一个 <pathSeparator> 属性,如果它是一个空格,则此属性将不幸忽略该值。因此,我只是将其硬编码为某个值,然后使用build helper maven插件将其替换为我需要的空间:

      <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> 如果值只是一个空格,它就不起作用,所以我用它周围的文本来包围它。

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