Maven Jar 插件详解

maven-jar-plugin

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

jar:jar 插件目标

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

必选元素

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

可选元素

  • 。要使用的打包配置。参见 Maven Archiver 的资料。
  • 。要添加到生成的工件的 classifier。如果给定,工件将作为补充工件附加。如果没有给出,这将创建作为默认行为的主工件。如果您第二次尝试这样做而不使用分类器,构建将失败。
  • 。要包含的文件列表。指定为文件集模式,该模式与内容打包到 JAR 中的输入目录相关。
  • 。要排除的文件列表。指定为文件集模式,该模式与内容打包到 JAR 中的输入目录相关。
  • 。要求该插件构建一个新的 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 的值。
  • 。可重复输出存档项的时间戳,格式为 ISO 8601 yyyy-MM-dd'T'HH:mm:ssXXX 或表示自历元(如 SOURCE_DATE_EPOCH,UNIX 时间戳,定义为自 1970 年 1 月 1 日 00:00:00 UTC 以来的秒数,不包括闰秒)起秒数的整数。默认为 ${project.build.outputTimestamp} property 的值。
  • 。跳过创建空存档。默认为 false

jar:test-jar 插件目标

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

必选元素

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

可选元素

  • 。要使用的打包配置。参见下面关于 Maven Archiver 的介绍。
  • 。用于 test-jarclassifier。默认为 tests
  • 。要包含的文件列表。指定为文件集模式,该模式与内容打包到 JAR 中的输入目录相关。
  • 。要排除的文件列表。指定为文件集模式,该模式与内容打包到 JAR 中的输入目录相关。
  • 。要求该插件构建一个新的 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 的值。
  • 。可重复输出存档项的时间戳,格式为 ISO 8601 yyyy-MM-dd'T'HH:mm:ssXXX 或表示自历元(如 SOURCE_DATE_EPOCH,UNIX 时间戳,定义为自 1970 年 1 月 1 日 00:00:00 UTC 以来的秒数,不包括闰秒)起秒数的整数。默认为 ${project.build.outputTimestamp} property 的值。
  • 。跳过创建空存档。默认为 false
  • 。将其设置为 true 以绕过 test-jar 生成。不推荐使用,但有时使用起来相当方便。默认为 maven.test.skip property 的值。

示例

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

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

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


  ...
  
    
      ...
      
        org.apache.maven.plugins
        maven-jar-plugin
        3.2.0
        
          
            package
            
              jar
            
            
              client
              
                **/service/*
              
            
          
        
      
      ...
    
  
  ...

如何创建包含测试类的 jar

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

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

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


  ...
  
    
      ...
      
        org.apache.maven.plugins
        maven-jar-plugin
        3.2.0
        
          
            
              test-jar
            
          
        
      
      ...
    
  
  ...

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


  ...
  
    
      groupId
      artifactId
      tests
      test-jar
      version
      test
    
  
  ...

基于这种配置,将生成两个 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 的可传递依赖项,您应该创建一个单独的项目。


   groupId
    artifactId-tests
    version
  ...

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

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


  ...
  
    
      groupId
      artifactId-tests
      version
      test
    
  
  ...

Apache Maven Archiver

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


  
  
  
  
  
 
  
  
    
    
    
    
    
    
    
    
    
    
    
    
  
  
    value
  
  
    
      
      
        value
      
    
  

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 版本,它是该插件的第一个使用此新功能的版本。


  ...
  
    
      
        org.apache.maven.plugins
        maven-jar-plugin
        2.1
        ...
        
          
            
              true
              true
            
          
        
        ...
      
    
  
  ...

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

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 没有 / 元素,则清单中将不包含 Specification-VendorImplementation-Vendor 条目。

清单条目

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

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


  http://some.url.org/
  ...
  
    
      
        org.apache.maven.plugins
        maven-jar-plugin
        ...
        
          
            
              development
              ${project.url}
            
          
        
        ...
      
    
  
  ...

如上所述,您可以使用字面量,也可以将 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 条目将不在清单中。

manifestSections

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

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


  ...
  
    
      
        org.apache.maven.plugins
        maven-jar-plugin
        ...
        
          
            
              
                foo
                
                  nice foo
                
              
              
                bar
                
                  nice bar
                
              
            
          
        
        ...
      
    
  
  ...

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

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 参考。


  ...
  
    
      
        org.apache.maven.plugins
        maven-jar-plugin
        3.2.0
        
          
            true
            
              true
            
            
              development
              ${project.url}
              value
            
          
        
        ...
      
    
  
  ...

使用自己的清单文件

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

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


  ...
  
    
      
        org.apache.maven.plugins
        maven-jar-plugin
        ...
        
          
            src/main/resources/META-INF/MANIFEST.MF
          
        
        ...
      
    
  
  ...

设置类路径

将 Class-Path 条目添加到清单

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


  ...
  
    
      
        org.apache.maven.plugins
        maven-jar-plugin
        ...
        
          
            
              true
            
          
        
        ...
      
    
  
  ...
  
    
      commons-lang
      commons-lang
      2.1
    
    
      org.codehaus.plexus
      plexus-utils
      1.1
    
  
  ...

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

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。您需要告诉它使用哪个主类。这是通过 配置元素完成的。下面是一个示例 pom.xml,配置为添加类路径并将名为 fully.qualified.MainClass 的类用作主类:


  ...
  
    
      
        org.apache.maven.plugins
        maven-jar-plugin
        ...
        
          
            
              true
              fully.qualified.MainClass
            
          
        
        ...
      
    
  
  ...
  
    
      commons-lang
      commons-lang
      2.1
    
    
      org.codehaus.plexus
      plexus-utils
      1.1
    
  
  ...

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

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 文件时。这可以通过 配置元素实现。


  ...
  
    
      
         maven-war-plugin
         
           
             
               true
               lib/
             
           
         
      
    
  
  ...
  
    
      commons-lang
      commons-lang
      2.1
    
    
      org.codehaus.plexus
      plexus-utils
      1.1
    
  
  ...

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

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

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


  ...
  
    
      
        maven-jar-plugin
        2.3
        
          
            
              true
              lib/
              repository
            
          
        
      
    
  
  ...
  
    
      commons-lang
      commons-lang
      2.1
    
    
      org.codehaus.plexus
      plexus-utils
      1.1
    
  
  ...

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

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 元素以及 元素,如下所示:


  ...
  
    
      
         maven-war-plugin
         
           
             
               true
               custom
               WEB-INF/lib/$${artifact.groupIdPath}/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}
             
           
         
      
    
  
  ...
  
    
      commons-lang
      commons-lang
      2.1
    
    
      org.codehaus.plexus
      plexus-utils
      1.1
    
  
  ...

这个类路径布局比前面的示例要复杂一些。需要先了解一下 元素的值,该值内表达式应用的规则如下:

  • 从表达式中删除 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 插件允许您在其 描述符部分的 元素中做出此决定。

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

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

false
强制对自定义布局使用快照版本

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


    WEB-INF/lib/${artifact.groupIdPath}/${artifact.artifactId}-${artifact.baseVersion}${dashClassifier?}.${artifact.extension}

完整的示例配置如下所示:


  ...
  
    
      
         maven-war-plugin
         
           
             
               true
               custom
               WEB-INF/lib/${artifact.groupIdPath}/${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}
             
           
         
      
    
  
  ...

你可能感兴趣的:(Maven Jar 插件详解)