Maven Jar 插件详解

maven-jar-plugin

该插件提供了构建 JAR 包的功能。如果您喜欢对 JAR 包签名,请使用 Maven Jarsigner 插件。该插件有两个插件目标。

jar:jar 插件目标

该插件目标的全称为 org.apache.maven.plugins:maven-jar-plugin:3.2.0:jar,用于从当前项目构建一个 JAR。该插件绑定到了 package 生命周期阶段。

必选元素

  • <classesDirectory>。包含应打包到 JAR 中的类和资源文件的目录。默认为 ${project.build.outputDirectory} property 的值。
  • <outputDirectory>。包含生成的 JAR 的目录。默认为 ${project.build.directory} property 的值。

可选元素

  • <archive>。要使用的打包配置。参见 Maven Archiver 的资料
  • <classifier>。要添加到生成的工件的 classifier。如果给定,工件将作为补充工件附加。如果没有给出,这将创建作为默认行为的主工件。如果您第二次尝试这样做而不使用分类器,构建将失败。
  • <includes>。要包含的文件列表。指定为文件集模式,该模式与内容打包到 JAR 中的输入目录相关。
  • <excludes>。要排除的文件列表。指定为文件集模式,该模式与内容打包到 JAR 中的输入目录相关。
  • <forceCreation>。要求该插件构建一个新的 JAR 包,即使内容似乎没有任何变化。默认情况下,该插件查看输出的 JAR 是否存在,以及打包所用的输入是否更改。如果这些条件为真,插件将跳过 JAR 包的创建。当其他插件(如 maven-shade-plugin)被配置为 post-process jar 时,这不起作用。该插件无法检测到 post-process,因此将 post-processed 的 jar 留在原地。当这些插件不希望找到自己的输出作为输入时,这可能导致失败。将该参数设置为 true(默认为 false),通过强制该插件每次重新创建 jar 来避免这些问题。从 3.0.0 开始,该属性已从 jar.forceCreation 重命名为 maven.jar.forceCreation。默认为 maven.jar.forceCreation property 的值。
  • <outputTimestamp>。可重复输出存档项的时间戳,格式为 ISO 8601 yyyy-MM-dd'T'HH:mm:ssXXX 或表示自历元(如 SOURCE_DATE_EPOCH,UNIX 时间戳,定义为自 1970 年 1 月 1 日 00:00:00 UTC 以来的秒数,不包括闰秒)起秒数的整数。默认为 ${project.build.outputTimestamp} property 的值。
  • <skipIfEmpty>。跳过创建空存档。默认为 false

jar:test-jar 插件目标

该插件目标的全称为 org.apache.maven.plugins:maven-jar-plugin:3.2.0:test-jar,用于为当前项目构建测试类的 JAR。。该插件绑定到了 package 生命周期阶段。

必选元素

  • <testClassesDirectory>。包含应打包到 JAR 中的测试类和资源文件的目录。默认为 ${project.build.testOutputDirectory} property 的值。
  • <outputDirectory>。包含生成的 JAR 的目录。默认为 ${project.build.directory} property 的值。

可选元素

  • <archive>。要使用的打包配置。参见下面关于 Maven Archiver 的介绍。
  • <classifier>。用于 test-jarclassifier。默认为 tests
  • <includes>。要包含的文件列表。指定为文件集模式,该模式与内容打包到 JAR 中的输入目录相关。
  • <excludes>。要排除的文件列表。指定为文件集模式,该模式与内容打包到 JAR 中的输入目录相关。
  • <forceCreation>。要求该插件构建一个新的 JAR 包,即使内容似乎没有任何变化。默认情况下,该插件查看输出的 JAR 是否存在,以及打包所用的输入是否更改。如果这些条件为真,插件将跳过 JAR 包的创建。当其他插件(如 maven-shade-plugin)被配置为 post-process jar 时,这不起作用。该插件无法检测到 post-process,因此将 post-processed 的 jar 留在原地。当这些插件不希望找到自己的输出作为输入时,这可能导致失败。将该参数设置为 true(默认为 false),通过强制该插件每次重新创建 jar 来避免这些问题。从 3.0.0 开始,该属性已从 jar.forceCreation 重命名为 maven.jar.forceCreation。默认为 maven.jar.forceCreation property 的值。
  • <outputTimestamp>。可重复输出存档项的时间戳,格式为 ISO 8601 yyyy-MM-dd'T'HH:mm:ssXXX 或表示自历元(如 SOURCE_DATE_EPOCH,UNIX 时间戳,定义为自 1970 年 1 月 1 日 00:00:00 UTC 以来的秒数,不包括闰秒)起秒数的整数。默认为 ${project.build.outputTimestamp} property 的值。
  • <skipIfEmpty>。跳过创建空存档。默认为 false
  • <skip>。将其设置为 true 以绕过 test-jar 生成。不推荐使用,但有时使用起来相当方便。默认为 maven.test.skip property 的值。

示例

如何从项目中创建附加的 jar 工件

通过添加 <includes>/<include><excludes>/<exclude> 指定要包括或排除的文件集模式列表,并在 pom.xml 中添加 classifier

注意:jar-plugin 必须在新的 execution 中定义,否则它将替换 jar-plugin 的默认使用,而不是添加第二个工件。classifier 还需要创建多个工件。

<project>
  ...
  <build>
    <plugins>
      ...
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.2.0</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>jar</goal>
            </goals>
            <configuration>
              <classifier>client</classifier>
              <includes>
                <include>**/service/*</include>
              </includes>
            </configuration>
          </execution>
        </executions>
      </plugin>
      ...
    </plugins>
  </build>
  ...
</project>

如何创建包含测试类的 jar

当您想要创建一个包含测试类的 jar 时,您可能想要重用这些类。有两种方法可以解决此问题:

  • 使用当前项目中的 test-classes 创建一个附加的 jar,并释放其范围为 test 的可传递依赖项。
  • 使用 test-classes 创建一个单独的项目。
简单方式

您可以生成一个包含测试类和资源的 jar。

<project>
  ...
  <build>
    <plugins>
      ...
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.2.0</version>
        <executions>
          <execution>
            <goals>
              <goal>test-jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      ...
    </plugins>
  </build>
  ...
</project>

要在其他项目中重用此工件,必须使用 test-jartype 来声明此依赖关系:

<project>
  ...
  <dependencies>
    <dependency>
      <groupId>groupId</groupId>
      <artifactId>artifactId</artifactId>
      <classifier>tests</classifier>
      <type>test-jar</type>
      <version>version</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  ...
</project>

基于这种配置,将生成两个 jar 文件。第一个包含来自 src/main/java 的类,而第二个包含来自 src/test/java 的类。生成的 jar 文件遵循命名模式 artifactId-version.jar(第一个)和 artifactId-version-classifier.jar(第二个)。artifactIdversions 部分将替换为 pom.xml 文件中给定的值。classifier 将被设置为 tests,这是 maven-jar-plugin 的默认值,如果需要,可以使用 jar 插件目标中的配置对其进行更改。

注意:此解决方案的缺点是您不会自动获取范围为 test 的可传递的依赖项。Maven 只解析 compile 范围的依赖项,因此您必须手动添加所有其他必需的范围为 test 的依赖项。

首选方式

为了让 Maven 解析所有范围为 test 的可传递依赖项,您应该创建一个单独的项目。

<project>
   <groupId>groupId</groupId>
    <artifactId>artifactId-tests</artifactId>
    <version>version</version>
  ...
</project>
  • 将要共享的源文件从原始项目的 src/test/java 目录移动到该新建项目的 src/main/java 目录中。当然,资源也可以像这样移动。
  • 将所需的 test 范围的依赖项从原始项目移动到该新建项目,并删除该范围(即,将其更改为 compile 范围)。是的,这意味着 junit 依赖项(或任何其他测试框架依赖项)也会获得默认范围。您可能还需要添加一些特定于项目的依赖项,以便重新编译。

现在您有了可重用的测试类,您可以按照习惯引用它:

<project>
  ...
  <dependencies>
    <dependency>
      <groupId>groupId</groupId>
      <artifactId>artifactId-tests</artifactId>
      <version>version</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  ...
</project>

Apache Maven Archiver

许多打包插件(比如,maven-jar-plugin、maven-war-plugin)都是使用 Maven Archiver 处理 JAR 的内容和清单配置。

<archive>
  <addMavenDescriptor/>
  <compress/>
  <forced/>
  <index/>
  <pomPropertiesFile/>
 
  <manifestFile/>
  <manifest>
    <addClasspath/>
    <addDefaultEntries/>
    <addDefaultImplementationEntries/>
    <addDefaultSpecificationEntries/>
    <addBuildEnvironmentEntries/>
    <addExtensions/>
    <classpathLayoutType/>
    <classpathPrefix/>
    <customClasspathLayout/>
    <mainClass/>
    <packageName/>
    <useUniqueVersions/>
  </manifest>
  <manifestEntries>
    <key>value</key>
  </manifestEntries>
  <manifestSections>
    <manifestSection>
      <name/>
      <manifestEntries>
        <key>value</key>
      </manifestEntries>
    <manifestSection/>
  </manifestSections>
</archive>

archive

  • addMavenDescriptor。创建的归档文件是否包含以下两个 Maven 文件(默认为 true):
    • pom.xml 文件。该文件位于 META-INF/maven/${groupId}/${artifactId}/pom.xml
    • pom.properties 文件。该文件位于 META-INF/maven/${groupId}/${artifactId}/pom.properties
  • compress。是否对存档进行压缩。默认值为 true
  • forced。是否强制重新创建存档。将此选项设置为 false(默认值为 true),意味着将所包含文件的时间戳与目标存档的时间戳进行比较,并重建存档,前提是后者的时间戳小于前者的时间戳。检查时间戳通常会带来性能提升(特别是,如果构建中的以下步骤被抑制,如果没有重新创建归档文件),代价是您会不时得到不准确的结果。特别是,不会检测到源文件的删除。归档程序不一定支持检查最新版本。如果是这样,将此选项设置为 true 将被忽略。
  • index。创建的存档文件是否包含 INDEX.LIST 文件。默认值为 false
  • pomPropertiesFile。使用此选项覆盖自动创建的 pom.properties 文件(仅当 addMavenDescriptor 设置为 true 时)。
  • manifestFile。有了它,您可以提供自己的清单文件。
  • manifestEntries。要添加到清单的键/值对的列表。
  • manifestSections。参考下面的介绍。
  • manifest。参考下面的介绍。

pom.properties 文件的内容

自动创建的 pom.properties 文件将包含以下内容 :

artifactId=${project.artifactId}
groupId=${project.groupId}
version=${project.version}

manifest

  • addClasspath。是否创建 Class-Path 清单条目。默认值为 false

  • addDefaultEntries。如果清单将包含以下条目:

    Created-By: Maven Archiver ${maven-archiver.version}
    Build-Jdk-Spec: ${java.specification.version}
    

    从 3.5.0 开始,可以使用 MavenArchiver.setCreatedBy(...) API 覆盖 Created-By 条目的默认值。默认值为 true

  • addDefaultImplementationEntries。如果清单将包含以下条目:

    Implementation-Title: ${project.name}
    Implementation-Version: ${project.version}
    Implementation-Vendor: ${project.organization.name}
    

    默认值为 false

  • addDefaultSpecificationEntries。如果清单将包含以下条目:

    Specification-Title: ${project.name}
    Specification-Version: ${project.artifact.selectedVersion.majorVersion}.${project.artifact.selectedVersion.minorVersion}
    Specification-Vendor: ${project.organization.name}
    

    默认值为 false

  • addBuildEnvironmentEntries。如果清单将包含以下条目:

    Build-Tool: ${maven.build.version}
    Build-Jdk: ${java.version} (${java.vendor})
    Build-Os:  ${os.name} (${os.version}; (${os.arch})
    

    默认值为 false

  • addExtensions。是否创建 Extension-List 清单条目。默认值为 false

  • classpathLayoutType。在所创建的 Class-Path 中格式化条目时要使用的布局类型。有效值包括:simplerepository(与Maven类路径布局相同)和 custom。注意:如果指定 custom 的类型,还必须设置 customClasspathLayout。默认值为 simple

  • classpathPrefix。将作为所有 Class-Path 项前缀的文本。默认值为空字符串 “”

  • customClasspathLayout。在 classpathLayoutType 中设置的布局类型值为 custom 时使用的布局表达式。表达式将根据类路径相关对象的以下有序列表进行计算:

    • 当前 Artifact 实例(如果存在)。
    • 来自上述 Artifact 的当前 ArtifactHandler 实例。

    注意:如果指定 custom 布局类型,则必须设置该布局表达式。

  • mainClassMain-Class 清单项。

  • packageName。名为 Package 清单条目。

  • useUniqueVersions。是否使用唯一的时间戳快照版本而不是 -SNAPSHOT。默认值为 true

manifestSection

  • name。节的名称。
  • manifestEntries。要添加到清单的键/值对的列表。java.util.Map 类型。

示例

清单

Maven Archiver 创建的默认清单将包含以下信息:

Manifest-Version: 1.0
Created-By: Apache Maven ${maven.version}
Build-Jdk: ${java.version}

注意:Build-Jdk 条目不考虑 toolchains 配置。它与运行 Maven 实例的 JDK 版本相同。

从版本 2.1 开始,默认情况下 Maven Archiver 不再在清单中创建实现和规范细节。如果您希望它们出现在清单中,则必须在配置中明确说明。

注意:因为这是 Maven Archiver 的最新变化,不同的插件可能已经开始使用它,也可能尚未开始使用它。请检查您想要使用的插件的文档。在本例中,我们使用maven-jar-plugin 插件的 2.1 版本,它是该插件的第一个使用此新功能的版本。

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.1</version>
        ...
        <configuration>
          <archive>
            <manifest>
              <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
              <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
            </manifest>
          </archive>
        </configuration>
        ...
      </plugin>
    </plugins>
  </build>
  ...
</project>

生成的清单将包含以下信息:

Manifest-Version: 1.0
Created-By: Apache Maven ${maven.version}
Build-Jdk: ${java.version}
Specification-Title: ${project.name}
Specification-Version: ${project.artifact.selectedVersion.majorVersion}.${project.artifact.selectedVersion.minorVersion}
Specification-Vendor: ${project.organization.name}
Implementation-Title: ${project.name}
Implementation-Version: ${project.version}
Implementation-Vendor: ${project.organization.name}

注意:如果 pom.xml 没有 <organization>/<name> 元素,则清单中将不包含 Specification-VendorImplementation-Vendor 条目。

清单条目

如果您发现 Maven Archiver 的其他配置选项不足以操作清单,那么可以向清单中添加您自己的条目。这是通过 <manifestEntries> 配置元素完成的。在本例中,我们将通过在 maven-jar-plugin 插件的 <configuration>/<archive> 元素中指定所需内容,向清单中添加一些条目。

注意:与这里的所有示例一样,此配置可以用于所有使用 Maven Archiver 的插件,而不仅仅是本示例中的 Maven jar 插件。

<project>
  <url>http://some.url.org/</url>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        ...
        <configuration>
          <archive>
            <manifestEntries>
              <mode>development</mode>
              <url>${project.url}</url>
            </manifestEntries>
          </archive>
        </configuration>
        ...
      </plugin>
    </plugins>
  </build>
  ...
</project>

如上所述,您可以使用字面量,也可以将 POM 中的值插值到字面量中,或者只使用直接的 POM 表达式。因此,在创建的 jar 中,结果清单将是这样的:

Manifest-Version: 1.0
Created-By: Apache Maven ${maven.version}
Build-Jdk: ${java.version}
mode: development
url: http://some.url.org/

注意:如果 pom.xml 没有通过插值引用的 <url> 元素,那么 url 条目将不在清单中。

manifestSections

<manifestSections> 元素提供了一种添加自定义清单部分的方法。它包含 <manifestSection> 元素的列表。

注意:与这里的所有示例一样,此配置可以用于所有使用 Maven Archive r的插件,而不仅仅是本示例中的 Maven jar 插件。

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        ...
        <configuration>
          <archive>
            <manifestSections>
              <manifestSection>
                <name>foo</name>
                <manifestEntries>
                  <id>nice foo</id>
                </manifestEntries>
              </manifestSection>
              <manifestSection>
                <name>bar</name>
                <manifestEntries>
                  <id>nice bar</id>
                </manifestEntries>
              </manifestSection>
            </manifestSections>
          </archive>
        </configuration>
        ...
      </plugin>
    </plugins>
  </build>
  ...
</project>

以下内容将出现在清单中:

Manifest-Version: 1.0
Created-By: Apache Maven ${maven.version}
Build-Jdk: ${java.version}

Name: foo
id: nice foo

Name: bar
id: nice bar

自定义清单

清单的默认内容在 Maven Archiver 的文档中描述。从版本 2.1 开始,maven-jar-plugin 插件使用 Maven Archiver 3.5.0。这意味着默认情况下,maven-jar-plugin 插件不再在清单中创建规范和实现细节,如果您想要配置这些,则必须显式配置。

可以使用 archive 配置元素更改默认清单。下面是一些可用的配置选项。有关更多信息,请参阅 Maven Archiver 参考。

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.2.0</version>
        <configuration>
          <archive>
            <index>true</index>
            <manifest>
              <addClasspath>true</addClasspath>
            </manifest>
            <manifestEntries>
              <mode>development</mode>
              <url>${project.url}</url>
              <key>value</key>
            </manifestEntries>
          </archive>
        </configuration>
        ...
      </plugin>
    </plugins>
  </build>
  ...
</project>

使用自己的清单文件

默认情况下,Maven Archiver 为您创建清单文件。有时使用自己手工制作的清单文件很有用。假设您想使用清单文件 src/main/resources/META-INF/MANIFEST.MF。这是通过将 <manifestFile> 元素的值设置为您自己的清单文件位置来完成的。您自己清单文件的内容将与 Maven Archiver 创建的条目合并。如果在自己的清单文件中指定一个条目,它将覆盖 Maven Archiver 创建的值。

注意:与这里的所有示例一样,这个配置可以在所有使用 Maven Archiver 的插件中使用,而不仅仅是本例中的 maven-jar-plugin 插件。

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        ...
        <configuration>
          <archive>
            <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
          </archive>
        </configuration>
        ...
      </plugin>
    </plugins>
  </build>
  ...
</project>

设置类路径

将 Class-Path 条目添加到清单

Maven Archiver 可以将项目的类路径添加到清单中。这是通过 <addClasspath> 配置元素完成的。

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        ...
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
            </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>

使用上述配置生成的清单如下所示:

Manifest-Version: 1.0
Created-By: Apache Maven ${maven.version}
Build-Jdk: ${java.version}
Class-Path: plexus-utils-1.1.jar commons-lang-2.1.jar
创建可执行的 jar

如果您想要创建一个可执行的 jar 文件,您需要相应地配置 Maven Archiver。您需要告诉它使用哪个主类。这是通过 <mainClass> 配置元素完成的。下面是一个示例 pom.xml,配置为添加类路径并将名为 fully.qualified.MainClass 的类用作主类:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        ...
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>fully.qualified.MainClass</mainClass>
            </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>

使用上述配置生成的清单如下所示:

Manifest-Version: 1.0
Created-By: Apache Maven ${maven.version}
Build-Jdk: ${java.version}
Main-Class: fully.qualified.MainClass
Class-Path: plexus-utils-1.1.jar commons-lang-2.1.jar

这时候,就可以使用形如 java -cp jar-file-path 的命令来运行该 jar 包中的主类了。

更改类路径:定义类路径目录前缀

有时,能够更改类路径是很有用的,例如在创建瘦 war 文件时。这可以通过 <classpathPrefix> 配置元素实现。

<project>
  ...
  <build>
    <plugins>
      <plugin>
         <artifactId>maven-war-plugin</artifactId>
         <configuration>
           <archive>
             <manifest>
               <addClasspath>true</addClasspath>
               <classpathPrefix>lib/</classpathPrefix>
             </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>

使用上述配置生成的清单类路径如下所示:

Class-Path: lib/plexus-utils-1.1.jar lib/commons-lang-2.1.jar
更改类路径:使用 Maven 仓库样式的类路径

有时,您可能希望在归档中包含 Maven 仓库样式的目录结构。如果希望引用清单类路径中那些目录中的依赖项,请尝试使用值为 repository<classpathLayoutType> 元素,如下所示:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.3</version>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <classpathPrefix>lib/</classpathPrefix>
              <classpathLayoutType>repository</classpathLayoutType>
            </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>

使用上述配置生成的清单类路径如下所示:

Class-Path: lib/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar lib/commons-lang/commons-lang/2.1/commons-lang-2.1.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. 前缀(如果存在)。
  • 尝试使用反射将表达式解析为对 Artifact 的引用。例如,artifactId 变为对方法 getArtifactId() 的引用。
  • 尝试将表达式解析为对当前 ArtifactArtifactHandler 的引用再次使用反射(例如,extension 变成了对方法 getExtension() 的引用)。
  • 尝试将表达式解析为特殊情况 Properties 实例中的 key,该实例包含以下映射:
    • dashClassifier:如果 Artifact 有一个 classifer,它将是 -$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
处理快照版本

根据构建存档的方式,您可以通过使用 -snapshot 后缀指定是否包含快照依赖项,或者是否使用该快照依赖项的唯一时间戳和内部版本号。例如,Assembly 插件允许您在其 <dependencySet> 描述符部分的 <outputFileNameMapping> 元素中做出此决定。

使用 simple (默认)或仓库样式的类路径布局时强制使用快照版本

要强制使用 -SNAPSHOT 版本命名,只需禁用 <useUniqueVersions> 配置元素,如下所示:

<useUniqueVersions>false</useUniqueVersions>
强制对自定义布局使用快照版本

要强制使用 -SNAPSHOT 版本命名,只需在上面的自定义布局示例中将 $artifact.version 替换为 $artifact.baseVersion,如下所示:

<customClasspathLayout>
    WEB-INF/lib/${artifact.groupIdPath}/${artifact.artifactId}-${artifact.baseVersion}${dashClassifier?}.${artifact.extension}</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>
  ...
</project>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容