Maven Jar 插件详解

2021-09-17  本文已影响0人  rosy_dawn

maven-jar-plugin

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

jar:jar 插件目标

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

必选元素

可选元素

jar:test-jar 插件目标

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

必选元素

可选元素

示例

如何从项目中创建附加的 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 时,您可能想要重用这些类。有两种方法可以解决此问题:

简单方式

您可以生成一个包含测试类和资源的 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>

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

<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

pom.properties 文件的内容

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

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

manifest

manifestSection

示例

清单

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> 元素的值,该值内表达式应用的规则如下:

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

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>
上一篇 下一篇

猜你喜欢

热点阅读