我很擅长使用Maven来构建我的Java项目,并遇到了一个我不知道如何处理的情况。
我有一个具有3个依赖项的Java应用程序,我们称之为a
,b
和c
。但是,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>
a
和b
工件在POM级别列为依赖关系,因为它们与平台无关,并且不会与配置文件一起激活。为简洁起见,此处未显示它们。
现在我想构建一个项目的可执行JAR,并将a
,b
和c
包含在我生成的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-dependencies
和jar: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.jar
或c-win32-x86_64-1.0.0.jar
,具体取决于有效的个人资料,我希望它最终为c-1.0.0.jar
。
将dependency:copy
与destFileName
而不是dependency:copy-dependencies
一起使用会产生正确的文件名,但Class-Path
中的条目仍然会引用“完全限定”的工件名称(即lib/c-win32-x86-1.0.0.jar
)。
我是以错误的方式来做这件事的吗?有没有更简单的方法来完成我想要做的事情?
答案 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>
配置的值,理解在解析值中的表达式时应用的规则是有用的:
<customClasspathLayout>
。'artifact.'
成为对方法'artifactId'
的引用)。'getArtifactId()'
成为对方法'extension'
的引用)。'getExtension()'
:如果工件有分类器,则为'dashClassifier'
,否则为空字符串。'- $artifact.classifier'
:这是'dashClassifier?'
。'dashClassifier'
:这相当于'groupIdPath'
,所有'$artifact.groupId'
个字符都替换为'.'
。使用上述配置生成的清单类路径如下所示:
'/'
我希望这可能有所帮助。