【问题标题】:Rename profile activated dependency when building executable JAR构建可执行 JAR 时重命名配置文件激活的依赖项
【发布时间】:2013-03-27 13:12:02
【问题描述】:

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

我有一个具有 3 个依赖项的 Java 应用程序,我们称它们为 abc。但是,c 将是不同的工件,具体取决于我们构建的平台,所以我使用配置文件来实现这一点。这是我pom.xml的一个sn-p:

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

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

    这个类路径布局比前面的例子更复杂一些。要了解如何解释 &lt;customClasspathLayout&gt; 配置的值,了解解析值中的表达式时应用的规则很有用:

    1. 如果存在,从表达式中删除前缀'artifact.'
    2. 尝试使用反射将表达式解析为对工件的引用(例如,'artifactId' 变为对方法 'getArtifactId()' 的引用)。
    3. 尝试将表达式解析为对当前 Artifact 的 ArtifactHandler 的引用,再次使用反射(例如,'extension' 成为对方法 'getExtension()' 的引用)。
    4. 尝试将表达式解析为特殊情况 Properties 实例中的键,该实例包含以下映射:
      • '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
    

    我希望这会有所帮助。

    【讨论】:

    • 我想赞成这个答案,但它实际上是我已经看过的页面的复制/粘贴,不能回答我的问题。不过谢谢。
    猜你喜欢
    • 2010-12-11
    • 2014-06-11
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多