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

时间:2009-12-15 09:39:18

标签: java maven-2 version

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

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

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

5 个答案:

答案 0 :(得分: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>

将它们拉出来的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>

这显示如下:

Version: 2.0.1-SNAPSHOT-QA

SVN Revision: 932

答案 1 :(得分:7)

当然,通过向POM添加<filtering>标记并将其设置为true,可以将变量包含在资源中并filtered与maven-resource-plugin一起使用:

...
<resource>
  <directory>src/main/resources</directory>
  <filtering>true</filtering>
</resource>
...

您可以使用此功能来读取和替换属性文件中的${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

如您所见,您会在其中找到pom.xmpom.properties文件,如How do I add resources to my 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

所以你可以用这样的(伪代码)加载这个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");

答案 2 :(得分:7)

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

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

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
....
<build>

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

pom.version=${pom.version}

现在,当您执行“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;
    }
}

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

<build>
    <finalName>my-killer-app-${pom.version}</finalName>
...
</build>

现在,如果您将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>

当您执行“mvn install”时,war文件名也包括版本号:

my-killer-app-01.02.879.war

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

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

    public String getVersion() {
        return VERSION;
    }
}

答案 3 :(得分:5)

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

查看Maven resource plugin文档,它会告诉您它是如何完成的。我认为您应该能够使用${version}替换该版本。虽然没有工作的maven安装在这里进行测试。

答案 4 :(得分:1)

在答案中,我们看到“加载属性文件”方法的一些变体,我将使用另一个与 Maven 3.5 一起使用的替代版本附加到该方法,但也可能旧版本。


第0步pom.xml

你只需要在pom.xml中做一件事;打开一个名为资源过滤的东西。通过查找<build>标记并将您希望过滤的资源文件夹放在那里,可以轻松完成此操作。它将如下所示:

<project ...>
  ...
  <build>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
    </resources>
    ...
  </build>
  ...
</project>

注意: 省略号...表示代码被省略

如果您愿意,您也可以添加自定义变量,但这不是必需的

<project ...>
  <properties>
    <build.version>1.1-SNAPSHOT</build.version>
  </properties>
  ...
</project>


步骤1属性文件

创建一个.properties文件并将其放在maven资源文件中。我要打电话给我application.properties。为简单起见,我将把它放在默认资源文件夹中; src/main/resources但您可以将其编辑到几乎任何您喜欢的文件夹中。

|-- pom.xml
|-- src
   |-- main
      |-- java
      |-- webapp
      |-- resources
         `-- application.properties

application.properties文件中,我将添加我想要的版本属性:

author=eFox
build=${build.version}
version=${project.version} # This is the default maven variable that you could and should use.


第2步* .JSP页面

这是我的方法与上述版本不同的地方。不是将属性文件作为Property类加载,而是加载META-INF pom.properties或将其设为控制器类,我们将把它作为资源加载:

<%@ page import = "java.util.ResourceBundle" %> 
<% ResourceBundle resource = ResourceBundle.getBundle("application");
  String version = resource.getString("version");
  String author = resource.getString("author");%>
<html>
  <head>
    ...
  </head>
  <body>
    ...
    Site version: <%=version %> by <%=author%>
  </body>
</html>