在构建可执行JAR时,重命名配置文件激活的依赖项



我对使用Maven构建我的Java项目相当陌生,并且遇到了我不知道如何处理的情况。

我有一个Java应用程序,它有3个依赖项,我们称它们为a, bc。然而,c将是一个不同的工件,这取决于我们正在构建的平台,所以我使用配置文件来实现这一点。这是我的pom.xml的一个片段:

<profiles>
  <profile>
    <id>win32</id>
    <activation>
      <os>
        <family>windows</family>
        <arch>x86</arch>
      </os>
    </activation>
    <dependencies>
      <dependency>
        <groupId>com.seanbright</groupId>
        <artifactId>c-win32-x86</artifactId>
        <version>1.0.0</version>
      </dependency>
    </dependencies>
  </profile>
  <profile>
    <id>win64</id>
    <activation>
      <os>
        <family>windows</family>
        <arch>amd64</arch>
      </os>
    </activation>
    <dependencies>
      <dependency>
        <groupId>com.seanbright</groupId>
        <artifactId>c-win32-x86_64</artifactId>
        <version>1.0.0</version>
      </dependency>
    </dependencies>
  </profile>
</profiles>

ab工件在POM级别被列为依赖项,因为它们与平台无关,并且不随概要文件一起激活。为简洁起见,这里没有显示它们。

现在我想为我的项目构建一个可执行的JAR,并将abc与从我的代码生成的JAR一起包含在lib/目录中,所以我最终会得到这样的东西:

target/my-project-1.0.0.jar
target/lib/a-1.0.0.jar
target/lib/b-1.0.0.jar
target/lib/c-1.0.0.jar

my-project-1.0.0.jar中的清单将具有适当的类路径,以便可以双击它,应用程序将启动。我使用dependency:copy-dependenciesjar:jar目标使所有这些工作:

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-dependency-plugin</artifactId>
      <version>2.7</version>
      <executions>
        <execution>
          <id>copy-dependencies</id>
          <goals>
            <goal>copy-dependencies</goal>
          </goals>
          <configuration>
            <outputDirectory>${project.build.directory}/lib</outputDirectory>
            <overWriteReleases>false</overWriteReleases>
            <overWriteSnapshots>false</overWriteSnapshots>
            <overWriteIfNewer>true</overWriteIfNewer>
            <includeScope>runtime</includeScope>
          </configuration>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jar-plugin</artifactId>
      <version>2.4</version>
      <configuration>
        <archive>
          <manifest>
            <mainClass>com.seanbright.myproject.Launch</mainClass>
            <addClasspath>true</addClasspath>
            <classpathPrefix>lib/</classpathPrefix>
          </manifest>
        </archive>
      </configuration>
    </plugin>
  </plugins>
</build>

…它的工作原理。唯一的问题是,c被复制到lib/目录(并添加到清单中的Class-Path)作为c-win32-x86-1.0.0.jarc-win32-x86_64-1.0.0.jar,具体取决于活动配置文件,我希望它最终成为c-1.0.0.jar

使用dependency:copydestFileName而不是dependency:copy-dependencies会得到正确的文件名,但是Class-Path中的条目仍然指向"完全限定的"工件名称(即lib/c-win32-x86-1.0.0.jar)。

我是不是走错路了?有没有更简单的方法来完成我想做的事情?

设置类路径:修改类路径:使用自定义类路径格式告诉我们如下:-

有时,您可能在自己的存档中拥有自定义格式的依赖文件,它不符合上述任何类路径布局。如果您希望在存档的清单类路径中为依赖文件定义自定义布局,请尝试使用值为'custom'<classpathLayoutType>元素,以及<customClasspathLayout>元素,如下所示:

<project>
  ...
  <build>
    <plugins>
      <plugin>
         <artifactId>maven-war-plugin</artifactId>
         <configuration>
           <archive>
             <manifest>
               <addClasspath>true</addClasspath>
               <classpathLayoutType>custom</classpathLayoutType>
               <customClasspathLayout>WEB-INF/lib/$${artifact.groupIdPath}/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>
             </manifest>
           </archive>
         </configuration>
      </plugin>
    </plugins>
  </build>
  ...
  <dependencies>
    <dependency>
      <groupId>commons-lang</groupId>
      <artifactId>commons-lang</artifactId>
      <version>2.1</version>
    </dependency>
    <dependency>
      <groupId>org.codehaus.plexus</groupId>
      <artifactId>plexus-utils</artifactId>
      <version>1.1</version>
    </dependency>
  </dependencies>
  ...
</project>

这个类路径布局比前面的例子要复杂一些。要理解如何解释<customClasspathLayout>配置的值,有必要了解在解析值

中的表达式时应用的规则:
  1. 如果存在,从表达式中删除前缀'artifact.'
  2. 尝试使用反射将表达式解析为对工件的引用(例如;'artifactId'变成了对方法'getArtifactId()'的引用。
  3. 尝试将表达式解析为对当前工件的ArtifactHandler的引用,再次使用反射(例如;'extension'变成对方法'getExtension()'的引用)。
  4. 尝试将表达式解析为特殊情况属性实例中的键,该实例包含以下映射:
    • 'dashClassifier':如果工件有分类器,这将是'- $artifact.classifier',否则这是一个空字符串。
    • 'dashClassifier?':这是'dashClassifier'的同义词。
    • 'groupIdPath':这相当于'$artifact.groupId',将所有'.'字符替换为'/'

使用上述配置生成的清单类路径看起来像这样:

Class-Path: WEB-INF/lib/org/codehaus/plexus/plexus-utils-1.1.jar WEB-INF/lib/commons-lang/commons-lang-2.1.jar

最新更新