我对使用Maven构建我的Java项目相当陌生,并且遇到了我不知道如何处理的情况。
我有一个Java应用程序,它有3个依赖项,我们称它们为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
)。
我是不是走错路了?有没有更简单的方法来完成我想做的事情?
设置类路径:修改类路径:使用自定义类路径格式告诉我们如下:-
有时,您可能在自己的存档中拥有自定义格式的依赖文件,它不符合上述任何类路径布局。如果您希望在存档的清单类路径中为依赖文件定义自定义布局,请尝试使用值为
'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>
配置的值,有必要了解在解析值
- 如果存在,从表达式中删除前缀
'artifact.'
。 - 尝试使用反射将表达式解析为对工件的引用(例如;
'artifactId'
变成了对方法'getArtifactId()'
的引用。 - 尝试将表达式解析为对当前工件的ArtifactHandler的引用,再次使用反射(例如;
'extension'
变成对方法'getExtension()'
的引用)。 - 尝试将表达式解析为特殊情况属性实例中的键,该实例包含以下映射:
-
'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