代码之家  ›  专栏  ›  技术社区  ›  Tom van Zummeren

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

  •  6
  • Tom van Zummeren  · 技术社区  · 16 年前

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

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

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

    5 回复  |  直到 16 年前
        1
  •  5
  •   falstro    16 年前

    看一看这本书 Maven resource plugin 文档,它会告诉你它是如何完成的。我想你应该可以用 ${version} . 不过,这里还没有一个可以运行的maven安装来测试它。

        2
  •  11
  •   the Tin Man    13 年前

    我解决这个问题的方式略有不同,因为我希望在服务的索引页上显示版本、svn修订版等。我使用buildnumber maven插件和war插件将值存储在清单中。

    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
    
        3
  •  7
  •   simbo1905    16 年前

    我的标准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>
    

    my-killer-app-01.02.879.war
    

    @Service("applicationVersion")
    public class ApplicationVersion {
        final static String VERSION = PomVersion.getVersion();
    
        public String getVersion() {
            return VERSION;
        }
    }
    
        4
  •  7
  •   David Mann Pascal Thivent    12 年前

    当然,变量可以包含在资源和 filtered 通过添加 <filtering> 标记POM并将其设置为true,如下所示:

    ...
    <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.xm pom.properties 文件,如中所述 How do I add resources to my JAR?

    这个 pom.xml 文件打包在JAR中,因此 Maven制造的每件艺术品 是自我描述的,也允许你 在您自己的数据库中使用元数据 简单的用法可能是检索 应用程序的版本。操作 在POM文件中,您需要 属性可以使用 标准JavaAPI,看起来像 以下:

    #Generated by Maven
    #Tue Oct 04 15:43:21 GMT-05:00 2005
    version=1.0-SNAPSHOT
    groupId=com.mycompany.app
    artifactId=my-app
    

    聚甲醛性能 文件中包含以下内容(伪代码):

    // 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");
    
        5
  •  1
  •   eFox    8 年前

    在这些答案中,我们看到了“加载属性文件”方法的一些变体,我将用另一个可用于 ,但也可能与旧版本。


    步骤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 application.properties . 为了简单起见,我将把它放在默认的资源文件夹中; src/main/resources 但是你可以把它编辑成你想要的任何文件夹。

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

    应用程序属性 文件我要添加所需的版本属性:

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


    步骤2*.JSP页面

    这就是我的方法与上述版本的不同之处。加载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>