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

时间:2013-03-27 13:12:03

标签: maven maven-dependency-plugin maven-profiles maven-jar-plugin

我很擅长使用Maven来构建我的Java项目,并遇到了一个我不知道如何处理的情况。

我有一个具有3个依赖项的Java应用程序,我们称之为abc。但是,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-Pathc-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)。

我是以错误的方式来做这件事的吗?有没有更简单的方法来完成我想要做的事情?

1 个答案:

答案 0 :(得分:1)

设置The Classpath:Altering The Classpath: Using a Custom Classpath Format告诉我们如下: -

  

有时,您可能在自己的存档中以自定义格式存在依赖关系存档,该存档不符合上述任何类路径布局。如果您希望在归档的清单类路径中为依赖关系归档定义自定义布局,请尝试使用值为<classpathLayoutType>的{​​{1}}元素以及'custom'元素,如下所示:< / p>

<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> 配置的值,理解在解析值中的表达式时应用的规则是有用的:

  1. 如果存在,请从表达式中删除前缀<customClasspathLayout>
  2. 尝试使用反射将表达式解析为对工件的引用(例如'artifact.'成为对方法'artifactId'的引用)。
  3. 尝试将表达式解析为对当前工件的ArtifactHandler的引用,再次使用反射(例如。'getArtifactId()'成为对方法'extension'的引用)。
  4. 尝试将表达式解析为特殊情况属性实例中的键,该实例包含以下映射:
    • 'getExtension()':如果工件有分类器,则为'dashClassifier',否则为空字符串。
    • '- $artifact.classifier':这是'dashClassifier?'
    • 的同义词
    • 'dashClassifier':这相当于'groupIdPath',所有'$artifact.groupId'个字符都替换为'.'
  5. 使用上述配置生成的清单类路径如下所示:

    '/'

    我希望这可能有所帮助。