Maven 2:如何在WAR文件中打包当前项目版本?

Tom*_*ren 6 java maven-2 version

我正在使用Maven 2来构建我的Java项目,我正在寻找一种方法来向用户呈现pom.xml的当前版本号(例如,使用Servlet或JSP).

据我所知,最好的方法是Maven将版本号作为文本文件打包到WAR中.这允许我从该文件中读取版本并以我想要的方式呈现它.

有谁知道一个插件可以为我做这样的事情?也许WAR插件可以这样配置?或者也许一起使用其他方法?

Mik*_*ell 11

我有点不同地解决了这个问题,因为我希望在服务的索引页面上显示版本,svn修订版等.我使用buildnumber-maven-plugin和war-plugin将值存储在清单中.

pom.xml片段:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>buildnumber-maven-plugin</artifactId>
    <executions>
      <execution>
        <phase>validate</phase>
        <goals>
          <goal>create</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
  <plugin>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
      <archive>
        <manifest>
          <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
        </manifest>
        <manifestEntries>
          <Implementation-Environment>${env}</Implementation-Environment>
          <Implementation-Build>${buildNumber}</Implementation-Build>
        </manifestEntries>
      </archive>
    </configuration>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>war</goal>
        </goals>
        <configuration>
          <classifier>${env}</classifier>
        </configuration>
      </execution>
    </executions>
  </plugin>
Run Code Online (Sandbox Code Playgroud)

将它们拉出来的JSP相当简单:

<%@ page language="java" pageEncoding="UTF-8"%>
<% 
java.util.jar.Manifest manifest = new java.util.jar.Manifest();
manifest.read(pageContext.getServletContext().getResourceAsStream("/META-INF/MANIFEST.MF"));
java.util.jar.Attributes attributes = manifest.getMainAttributes();

%>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Health Check</title>
  </head>
  <body>
    <h1>Health Check</h1>
    <h2>Version: <%=attributes.getValue("Implementation-Version")%>-<%=attributes.getValue("Implementation-Environment")%></h2>
    <h2>SVN Revision: <%=attributes.getValue("Implementation-Build")%></h2>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

这显示如下:

Version: 2.0.1-SNAPSHOT-QA

SVN Revision: 932
Run Code Online (Sandbox Code Playgroud)


Pas*_*ent 7

当然,变量可以包含在资源中,并通过向POM 添加标记并使用maven-resource-plugin进行过滤<filtering>,并将其设置为true,如下所示:

...
<resource>
  <directory>src/main/resources</directory>
  <filtering>true</filtering>
</resource>
...
Run Code Online (Sandbox Code Playgroud)

你可以使用这个功能来读取和替换${version}(或${project.version}${pom.version}对等同)的属性文件的例子.

但是,实际上,Maven默认提供您要查找的信息(除非您将其配置为不这样做,如果您不知道这一点,这是不太可能的).如果您解压缩Maven为您创建的WAR并查看它,您会看到以下内容:

|-- META-INF
|   |-- MANIFEST.MF
|   `-- maven
|       `-- com.mycompany.app
|           `-- my-app
|               |-- pom.properties
|               `-- pom.xml
|-- WEB-INF
|   |-- classes
|   |   |-- ...
|   |-- lib
|   |   |-- ...
|   `-- web.xml
|-- bar.jsp
|-- ...
`-- foo.jsp
Run Code Online (Sandbox Code Playgroud)

如您所见,您将在其中找到一个pom.xmpom.properties文件,如我如何向JAR添加资源中所述?:

pom.xmlpom.properties 文件打包在JAR以便由Maven的生产的每个工件是自描述的,也可以让你利用元数据在自己的应用程序,如有需要.一个简单的用途可能是检索应用程序的版本.在POM文件上操作需要使用一些Maven实用程序,但可以使用标准Java API来使用这些属性,如下所示:

#Generated by Maven
#Tue Oct 04 15:43:21 GMT-05:00 2005
version=1.0-SNAPSHOT
groupId=com.mycompany.app
artifactId=my-app
Run Code Online (Sandbox Code Playgroud)

所以你可以pom.properties用这样的东西加载这个文件(伪代码):

// Retrieve resource
InputStream is = getClass().getResourceAsStream( "/META-INF/maven/com.mycompany.app/my-app/pom.properties" );

// Do something with the resource, e.g. load it as Properties
Properties prop = new Properties();
prop.load(is);
String version = prop.getProperty("version");
Run Code Online (Sandbox Code Playgroud)


sim*_*905 7

我的标准Maven WAR插件的解决方案

向您构建部分添加资源标记,该部分启用过滤(也称为"搜索和替换"):

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
....
<build>
Run Code Online (Sandbox Code Playgroud)

然后在你的src/main/resources中添加一个version.properties文件,其中包含与标准maven构建变量之一匹配的任何过滤变量(你也可以使用过滤功能加载你自己的自定义变量):

pom.version=${pom.version}
Run Code Online (Sandbox Code Playgroud)

现在,当您执行"maven包"或maven安装时,它会将version.properties文件复制到WEB-INF/classes中并执行搜索和替换以将pom版本添加到文件中.

要使用Java实现此目的,请使用以下类:

public class PomVersion {
    final private static Logger LOGGER = LogManager.getLogger(PomVersion.class);

    final static String VERSION = loadVersion();

    private static String loadVersion() {
        Properties properties = new Properties();
        try {
            InputStream inStream = PomVersion.class.getClassLoader().getResourceAsStream("version.properties");
            properties.load(inStream);
        } catch (Exception e){
            LOGGER.warn("Unable to load version.properties using PomVersion.class.getClassLoader().getResourceAsStream(...)", e);
        }
        return properties.getProperty("pom.version");
    }

    public static String getVersion(){
        return VERSION;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,您只需调用PomVersion.getVersion()将pom文件的版本号放入页面即可.您还可以使用pom.xml中finalName中的filter变量为WAR文件指定相同的编号:

<build>
    <finalName>my-killer-app-${pom.version}</finalName>
...
</build>
Run Code Online (Sandbox Code Playgroud)

所以现在如果你在pom中设置你的应用程序版本是01.02.879:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.killer.app</groupId>
    <artifactId>my-killer-app</artifactId>
    <packaging>war</packaging>
    <name>This App Will Rule The World</name>
    <version>01.02.879</version>
    ...
</project>
Run Code Online (Sandbox Code Playgroud)

当您执行"mvn install"时,war文件名也包含版本号:

my-killer-app-01.02.879.war
Run Code Online (Sandbox Code Playgroud)

最后,如果您使用Spring,例如使用SpringMVC/SpringWebFlow,您可以创建一个使用该类的单例服务bean,以避免必须按名称引用低级类:

@Service("applicationVersion")
public class ApplicationVersion {
    final static String VERSION = PomVersion.getVersion();

    public String getVersion() {
        return VERSION;
    }
}
Run Code Online (Sandbox Code Playgroud)


fal*_*tro 5

您正在寻求过滤资源.甚至在war-plugin创建文件之前就已完成此操作.我很确定war-plugin在web.xml和manifest中打包了这个版本,但我不确定如何通过servlet API访问它们,但它也可能是一种有效的方法.

看看Maven资源插件文档,它会告诉你它是如何完成的.我认为你应该可以使用替换版本${version}.虽然没有工作maven安装在这里测试它.