1

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

我有一个具有 3 个依赖项的 Java 应用程序,我们称它们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>

和工件在 POM 级别被列为依赖项,因为它们与平台无关并且不会与配置文件一起激活ab为简洁起见,此处未显示它们。

现在我想为我的项目构建一个可执行的 JAR,并在从我的代码生成的 JAR 旁边的目录中包含、ab,所以我最终会得到这样的结果:clib/

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-dependenciesandjar: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:copywithdestFileName而不是会dependency:copy-dependencies产生正确的文件名,但其中的条目Class-Path仍然是指“完全限定”的工件名称(即lib/c-win32-x86-1.0.0.jar)。

我会以错误的方式解决这个问题吗?有没有更简单的方法来完成我想要做的事情?

4

1 回答 1

1

Set Up The Classpath:Altering The Classpath: Using a Custom Classpath Format告诉我们如下: -

有时,您可能在自己的存档中拥有自定义格式的依赖存档,它不符合上述任何类路径布局。如果您希望在存档的清单类路径中为依赖存档定义自定义布局,请尝试使用<classpathLayoutType>值为 的元素'custom'以及<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. 尝试使用反射将表达式解析为对 Artifact 的引用(例如,'artifactId'成为对方法的引用'getArtifactId()')。
  3. 尝试将表达式解析为对当前 Artifact 的 ArtifactHandler 的引用,再次使用反射(例如,'extension'成为对方法的引用'getExtension()')。
  4. 尝试将表达式解析为特殊情况 Properties 实例中的键,该实例包含以下映射:
    • 'dashClassifier': 如果 Artifact 有分类器,'- $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

我希望这可能会有所帮助。

于 2013-03-28T01:00:40.273 回答