Maven 2: Как упаковать текущую версию проекта в файл WAR? - PullRequest
6 голосов
/ 15 декабря 2009

Я использую Maven 2 для создания своего Java-проекта и ищу способ предоставить пользователю номер текущей версии pom.xml (например, с использованием сервлета или JSP).

Насколько я понимаю, лучшим способом было бы, чтобы Maven упаковывал номер версии в виде текстового файла в WAR. Это позволяет мне читать версию из этого файла и представлять ее так, как я хочу.

Кто-нибудь знает плагин, который может сделать что-то подобное для меня? Может быть, плагин WAR может быть настроен для этого? Или, может быть, использовать какой-то другой подход все вместе?

Ответы [ 5 ]

11 голосов
/ 21 декабря 2009

Я решил эту проблему немного по-другому, так как у меня было желание отобразить версию, версию 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
7 голосов
/ 30 апреля 2010

Мое решение для стандартного плагина 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 / и выполняет поиск и замену, чтобы добавить версию 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 на страницу. Вы также можете присвоить файлу WAR такой же номер, используя переменную фильтра в finalName в файле pom.xml:

<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", имя файла войны также включает номер версии:

my-killer-app-01.02.879.war

наконец, если вы интенсивно используете Spring, например SpringMVC / SpringWebFlow, вы можете создать одноэлементный компонент службы, который использует этот класс, чтобы избежать ссылки на класс низкого уровня по имени:

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

    public String getVersion() {
        return VERSION;
    }
}
7 голосов
/ 16 декабря 2009

Конечно, переменные могут быть включены в ресурсы и отфильтрованы с помощью плагина maven-resource-plugin, добавив тег <filtering> в POM и установив для него значение true, например:

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

И вы можете использовать эту функцию для чтения и замены ${version} (или ${project.version} или ${pom.version}, которые эквивалентны) в файле свойств, например.

Но, на самом деле, информация, которую вы ищете, по умолчанию доступна Maven (если только вы не настроили ее так, что очень маловероятно, если вы об этом не знаете). Если вы распакуете WAR, созданный Maven для вас, и посмотрите на нее, вы увидите следующее:

|-- 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 и, как объяснено в Как добавить ресурсы в мой 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");
5 голосов
/ 15 декабря 2009

Вы хотите сделать фильтрацию ресурсов. Это делается еще до того, как военный плагин создаст файл. Я почти уверен, что war-plugin упаковывает версию в web.xml и манифест, но я не уверен, как получить к ним доступ через API сервлетов, но это также может быть правильным подходом.

Взгляните на документацию по Maven , он расскажет вам, как это делается. Я думаю, что вы должны иметь возможность просто заменить версию, используя ${version}. У меня нет работающей установки maven, чтобы протестировать ее здесь.

1 голос
/ 31 октября 2017

Среди ответов мы видим несколько вариантов метода «загрузить файл свойств», и я собираюсь добавить к этому еще одну альтернативную версию, которая работает с Maven 3.5 , но, вероятно, также с старые версии.


Шаг 0 the pom.xml

Вам нужно сделать только одну вещь в pom.xml; включите то, что называется фильтрация ресурсов . Это легко сделать, найдя тег <build> и разместив там папку с ресурсами, которую вы хотите отфильтровать. Это будет выглядеть следующим образом:

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

Примечание: elipsis ... означает, что код опущен

при желании вы также можете добавить свои собственные переменные, но это не обязательно :

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