使用 Maven 時 manifest 的生成規則


使用 Maven 時 manifest 的生成規則

譯自 http://maven.apache.org/plugins/maven-jar-plugin/examples/manifest-customization.html

默認的 Manifest

由 Maven Archiver 創建的默認的 manifest 文件包含以下內容

Manifest-Version: 1.0
Created-By: Apache Maven ${maven.version}
Build-Jdk: ${java.version}
注意:Build-Jdk項 不會考慮工具鏈配置,這是和運行Maven實例時相同的JDK版本

增加實現和規范細節(Adding Implementation And Specification Details)

maven-jar-plugin 從 2.1 版本開始,開始使用 3.5.0 版本的 Maven Archiver, 該版本的 Maven Archiver 默認不會向 manifest 中添加 Implementation 和 Specification 細節。如果需要這些,你需要顯示進行配置。

注意:由於這是 Maven Archive 最近才有的變動,有些插件可能會還沒有開始采用它。你需要檢查相關插件的文檔。這個例子中,我們使用 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 文件內容如下

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-Vendor 和 Implementation-Vendor 條目不會出現在 manifest 文件中

自定義 Customization the Manifest

默認的 manifest 可以通過 archive 配置項來改變。下面例子中你可以找到一些可用的配置項。更多的信息參見 Maven Archiver reference

<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>

Manifest 條目(Manifest Entries)

如果你發現 Maven Archiver 配置項不足以操作 manifest,則可以向 manifest 添加自己的條目。 這是通過<manifestEntries>配置元素來完成的。

在下面的例子中,我們將通過在 maven-jar-plugin 的<configuration> / <archive>元素中指定所需的內容,向清單中添加一些條目。

注意:與這里的所有示例一樣,此配置可以在所有使用Maven Archiver的插件中使用,而不僅僅是本示例中的maven-jar-plugin。
<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>

如上所示,您可以使用字面值(literal values),也可以將POM中的值插入到字面值中,或者僅使用直接的POM表達式。 最后生成的 manifest 文件如下

Manifest-Version: 1.0
Created-By: Apache Maven ${maven.version}
Build-Jdk: ${java.version}
mode: development
url: http://some.url.org/
Note: If your pom.xml does not have the <url> element, referenced through interpolation, then the entry url will not be in the manifest.

Manifest Sections

<manifestSections> 元素提供了一種方式用來自定義 manifest 段 (manifest sections)。它包含一個 list of <manifestSection> elements

注意:與這里的所有示例一樣,此配置可以在所有使用Maven Archiver的插件中使用,而不僅僅是本示例中的maven-jar-plugin。

使用如下配置

<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 文件如下

Manifest-Version: 1.0
Created-By: Apache Maven ${maven.version}
Build-Jdk: ${java.version}
 
Name: foo
id: nice foo
 
Name: bar
id: nice bar

設置 Classpath

添加一個 Class-Path Entry 到 Manifest

通過<addClasspath> 配置項, Maven Archiver 可以把你項目的 classpath 添加到 manifest,

<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 如下

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 可執行 (Make The Jar Executable)

如果要創建可執行的jar文件,則需要相應地配置Maven Archiver。 您需要告訴它要使用哪個主類。 這是通過<mainClass>配置元素完成的。 下面是一個示例pom.xml,配置為添加 classpath 並將full.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

修改classpath,添加文件夾前綴(Altering The Classpath: Defining a Classpath Directory Prefix)

有時,能夠更改classpath 很有用,例如,在創建瘦的war文件(creating skinny war-files)時。 這可以通過<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>

生成的 manifest 文件中的 classpath 看起來像這樣:

Class-Path: lib/plexus-utils-1.1.jar lib/commons-lang-2.1.jar

修改classpath,使用 Maven Repository-Style Classpath

Occasionally, you may want to include a Maven repository-style directory structure in your archive. If you wish to reference the dependency archives within those directories in your manifest classpath, try using the <classpathLayoutType> element with a value of 'repository', like this:

<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>

The manifest classpath produced using the above configuration would look like this:

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

修改classpath,使用自定義的 classpath 格式 (Altering The Classpath: Using a Custom Classpath Format)

At times, you may have dependency archives in a custom format within your own archive, one that doesn't conform to any of the above classpath layouts. If you wish to define a custom layout for dependency archives within your archive's manifest classpath, try using the <classpathLayoutType> element with a value of 'custom', along with the <customClasspathLayout> element, like this:

<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>

This classpath layout is a little more involved than the previous examples. To understand how the value of the <customClasspathLayout> configuration is interpreted, it's useful to understand the rules applied when resolving expressions within the value:

  1. If present, trim off the prefix 'artifact.' from the expression.
  2. Attempt to resolve the expression as a reference to the Artifact using reflection (eg. 'artifactId' becomes a reference to the method 'getArtifactId()').
  3. Attempt to resolve the expression as a reference to the ArtifactHandler of the current Artifact, again using reflection (eg. 'extension' becomes a reference to the method 'getExtension()').
  4. Attempt to resolve the expression as a key in the special-case Properties instance, which contains the following mappings:
    • 'dashClassifier': If the Artifact has a classifier, this will be '-$artifact.classifier', otherwise this is an empty string.
    • 'dashClassifier?': This is a synonym of 'dashClassifier'.
    • 'groupIdPath': This is the equivalent of '$artifact.groupId', with all '.' characters replaced by '/'.

The manifest classpath produced using the above configuration would look like this:

Class-Path: WEB-INF/lib/org/codehaus/plexus/plexus-utils-1.1.jar WEB-INF/lib/commons-lang/commons-lang-2.1.jar

Handling Snapshot Versions

Depending on how you construct your archive, you may have the ability to specify whether snapshot dependency archives are included with the version suffix '-SNAPSHOT', or whether the unique timestamp and build-number for that archive is used. For instance, the Assembly Plugin allows you to make this decision in the <outputFileNameMapping> element of its <dependencySet> descriptor section.

Forcing the use of -SNAPSHOT versions when using the simple (default) or repository classpath layout

To force the use of '-SNAPSHOT' version naming, simply disable the <useUniqueVersions> configuration element, like this:

<useUniqueVersions>false</useUniqueVersions>

Forcing the use of -SNAPSHOT versions with custom layouts

To force the use of '-SNAPSHOT' version naming, simply replace '$artifact.version' with '$artifact.baseVersion' in the custom layout example above, so it looks like this:

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

The full example configuration would look like this:

<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>

使用你自己的 Manifest File

默認情況下,Maven Archiver 會為你產生 manifest 文件。你也可以通過配置項 manifestFile 來指定並使用你自己的 manifest 文件。自己指定的文件的內容,會被 merge 到 Maven Archiver 生成 manifest 文件中。如果你自己的文件和默認生成的文件有相同的條目,則自定義的條目會覆蓋掉自動生成的條目。

注意:與這里的所有示例一樣,此配置可以在所有使用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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM