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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1906266/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 23:43:41  来源:igfitidea点击:

Maven 2: How to package current project version in a WAR file?

javamaven-2version

提问by Tom van Zummeren

I am using Maven 2 to build my Java project and I am looking for a way to present the current version number of the pom.xml to the user (using a Servlet or JSP for example).

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

As far as I can see, the best way would be that Maven packages the version number as a text file into the WAR. This allows me to read the version from that file and present it the way I want.

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

Does anyone know of a plugin that can do something like that for me? Maybe the WAR plugin can be configured to do so? Or maybe using some other approach all together?

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

采纳答案by falstro

You're looking to do filtering of resources. This is done even before the war-plugin creates the file. I'm pretty sure the war-plugin packs the version in the web.xml and manifest, but I'm not sure how to access those through servlet APIs, but it might also be a valid approach.

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

Have a look at the Maven resource plugindocumentation, it'll tell you how it's done. I think you should be able to just substitue the version using ${version}. Haven't got a working maven installation to test it here though.

查看Maven 资源插件文档,它会告诉您它是如何完成的。我认为您应该能够使用${version}. 还没有一个有效的 maven 安装来测试它。

回答by Pascal Thivent

Of course, variables can be included in resources and filteredwih the maven-resource-plugin by adding a <filtering>tag to the POM and set it to true like this:

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

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

And you could use this feature to read and replace ${version}(or ${project.version}or ${pom.version}which are equivalent) in a properties file for example.

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

But, actually, the information you are looking for is available by default by Maven (unless you configured it to not do so which is very unlikely if you are not aware of that). If you unpack the WAR that Maven created for you and take a look at it you would see the following:

但是,实际上,您要查找的信息默认由 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

As you can see, you'll find a pom.xmand pom.propertiesfile in it and, as explained in How do I add resources to my JAR?:

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

The pom.xmland pom.propertiesfiles are packaged up in the JAR so that each artifact produced by Maven is self-describing and also allows you to utilize the metadata in your own application if the need arises. One simple use might be to retrieve the version of your application. Operating on the POM file would require you to use some Maven utilities but the properties can be utilized using the standard Java API and look like the following:

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

So you could just load this pom.propertiesfile with something like this (pseudo code):

所以你可以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");

回答by Mike Cornell

I solved this problem a little differently, as I had a desire to display version, svn revision, etc. on the index page of a service. I used the buildnumber-maven-plugin and the war-plugin to store the values in the manifest.

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

pom.xml snippet:

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>

The JSP to pull them out was fairly trivial:

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

This displayed something like:

这显示如下:

Version: 2.0.1-SNAPSHOT-QA

SVN Revision: 932

回答by simbo1905

My solution for the standard Maven WAR plugin

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

Add a resources tag to you build section which enables filtering (aka "search and replace"):

将资源标签添加到您的构建部分,以启用过滤(又名“搜索和替换”):

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

Then in your src/main/resources add a version.properties file containing any filter variables that matches one of the standard maven build variables (you can also use filtering feature to load your own custom variables):

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

pom.version=${pom.version}

Now when you do a "maven package" or a maven install it will copy the version.properties file into the WEB-INF/classes and do a search and replace to add the pom version into the file.

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

To get at this with Java use a class such as:

要使用 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;
    }
}

Now you can just call PomVersion.getVersion() to put the version number of the pom file into the page. You can also have the WAR file be given the same number by using a filter variable in the finalName within the pom.xml:

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

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

so now if you set your application version in your pom to be 01.02.879:

所以现在如果你在你的 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>

when you do an "mvn install" the war file name include the version number also:

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

my-killer-app-01.02.879.war

finally if you use Spring heavily such as with SpringMVC/SpringWebFlow you can make a singleton service bean which uses that class to avoid having to reference the low level class by name:

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

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

    public String getVersion() {
        return VERSION;
    }
}

回答by eFox

Among the answers we see a few variations of the "load a properties file" method and I'm going to append to that with yet another alternative version that works with Maven 3.5, but probably also with older versions.

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



Step 0 the pom.xml

步骤 0 pom.xml

You only need to do one thing in the pom.xml; turn on something called resource filtering. This is easily done by finding the <build>tag and placing your resource folder which you wish to filter in there. It will look like follows:

您只需要在pom.xml; 中做一件事;打开称为资源过滤的东西。这很容易通过找到<build>标签并将您希望过滤的资源文件夹放在那里来完成。它将如下所示:

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

Note:the elipsis ...means code is being omitted

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

if you want to, you may also add your custom variables, but this is not necessary:

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

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



Step 1 the properties file

步骤 1 属性文件

Create a .propertiesfile and place it in your maven resources file. I'm going to call mine application.properties. For simplicity I'm going to put it in the default resources folder; src/main/resourcesbut you can edit that to pretty much any folder you'd like.

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

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

In the application.propertiesfile I'm going to add the version property I want:

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

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



Step 2 the *.JSP page

第 2 步 *.JSP 页面

This is where my method differs from the above mentioned versions. Instead of loading the properties file as a Property class, load the META-INF pom.propertiesor make this a controller class, the we're going to load it as a resource:

这是我的方法与上述版本不同的地方。不是将属性文件作为属性类加载,而是加载 META-INFpom.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>