我正在使用Maven 2来构建我的Java项目,我正在寻找一种方法来向用户呈现pom.xml的当前版本号(例如,使用Servlet或JSP)。
据我所知,最好的方法是Maven将版本号作为文本文件打包到WAR中。这允许我从该文件中读取版本并以我想要的方式呈现它。
有没有人知道一个插件可以为我做这样的事情?也许WAR插件可以这样配置?或者也许一起使用其他方法?
答案 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.xm
和pom.properties
文件,如How do I add resources to my JAR?中所述:
pom.xml
和pom.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 一起使用的替代版本附加到该方法,但也可能旧版本。
你只需要在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>
创建一个.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.
这是我的方法与上述版本不同的地方。不是将属性文件作为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>