Знаток 2: Как упаковать текущую версию проекта в ВОЕННОМ файле?

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

Насколько я вижу, лучший способ состоял бы в том, что Знаток упаковывает номер версии как текстовый файл в ВОЙНУ. Это позволяет мне читать версию из того файла и представлять его способ, которым я хочу.

Кто-либо знает о плагине, который может сделать что-то как этот для меня? Возможно, ВОЕННЫЙ плагин может быть настроен, чтобы сделать так? Или возможно с помощью некоторого другого подхода все вместе?

6
задан Pascal Thivent 19 December 2009 в 17:34
поделиться

4 ответа

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.

Have a look at the Maven resource plugin documentation, 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.

5
ответ дан 8 December 2019 в 03:01
поделиться

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.

pom.xml snippet:

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

<%@ 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
11
ответ дан 8 December 2019 в 03:01
поделиться

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

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

И вы можете использовать эту возможность, чтобы прочитать и заменить ${версия} (или ${проект. 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 и, как объяснено в Как добавить ресурсы в JAR?:

pom.xml и pom.properties. файлы упакованы в JAR, так что... что каждый артефакт, произведенный Мэйвен. саморасписывается, а также позволяет использовать метаданные в своих приложение, если возникает необходимость. Один простым способом может быть извлечение версия вашего приложения. Работающий . в файле POM потребует от вас использовать некоторые утилиты Maven, но свойства могут быть использованы с помощью стандартный Java API и выглядят как следующее:

#Generated by Maven
#Tue Oct 04 15:43:21 GMT-05:00 2005
версия=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");
7
ответ дан 8 December 2019 в 03:01
поделиться

Мое решение для стандартного плагина 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-файла. Вы также можете присвоить файлу 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
ответ дан 8 December 2019 в 03:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: