在Maven中生成Version.java文件

时间:2022-03-08 00:00:39

I have a Java project that I build using an Ant script. I am trying to convert the project to Maven.

我有一个使用Ant脚本构建的Java项目。我正在尝试将项目转换为Maven。

One of the tasks generates a Java source file called Version.java that contains a static String representation of the compilation timestamp, as follows:

其中一个任务生成一个名为Version.java的Java源文件,其中包含编译时间戳的静态String表示形式,如下所示:

package com.foo.bar;
public final class Version {
 public static String VERSION="100301.1046";
}

The Ant task is very simple:

Ant任务非常简单:

<target name="version" depends="init" description="Create Version.java">
    <echo file="src/${package.dir}/Version.java" message="package ${package.name};${line.separator}" />
    <echo file="src/${package.dir}/Version.java" append="true" message="public final class Version {${line.separator}" />
    <echo file="src/${package.dir}/Version.java"
          append="true"
          message=" public static String VERSION=&quot;${buildtime}&quot;;${line.separator}" />
    <echo file="src/${package.dir}/Version.java" append="true" message="}${line.separator}" />
    <echo message="BUILD ${buildtime}" />
</target>

Is it possible to do something similar in Maven, using generate-sources, or some other simple method?

是否可以在Maven中使用生成源或其他简单方法执行类似的操作?

10 个解决方案

#1


76  

I don't think this is the good way to solve this kind of issue.

我不认为这是解决这类问题的好方法。

A better way is to put the version information in a properties file that will be read by your Java program:

更好的方法是将版本信息放在Java程序将读取的属性文件中:

Your properties file will contain the following line:

您的属性文件将包含以下行:

myapp.version=${project.version}

Then, in your pom.xml, indicate that the file will be filtered by Maven :

然后,在您的pom.xml中,指示该文件将由Maven过滤:

<resources>
    <resource>
        <directory>the/directory/that/contains/your/properties/file</directory>
        <filtering>true</filtering>
    </resource>
</resources>

When Maven will build your application, it will replace all ${...} by their value. By default, ${project.version} defines the version of the pom.xml (i.e. the value of the <version> tag).

当Maven构建您的应用程序时,它将用它们的值替换所有$ {...}。默认情况下,$ {project.version}定义pom.xml的版本(即 标记的值)。

Then, in your Java code, you will just need to load the properties file and retrieve the myApp.version property value.

然后,在Java代码中,您只需要加载属性文件并检索myApp.version属性值。

Note that you can use the Build Number plugin to set something more "complex" than just your current version (for example if you want to put the build time in your property).

请注意,您可以使用Build Number插件设置比当前版本更“复杂”的内容(例如,如果您想将构建时间放在属性中)。

#2


26  

You can also use maven-replacer-plugin if you feel ant is a little bit ugly: The pom enrty might be:

如果你觉得蚂蚁有点难看,你也可以使用maven-replacer-plugin:pom enrty可能是:

<project>
  ...
  <properties>
    <version.template.file>src/main/java/com/*Version.java.template</version.template.file>
<version.file>src/main/java/com/*/Version.java</version.file>
  </properties>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>com.google.code.maven-replacer-plugin</groupId>
            <artifactId>maven-replacer-plugin</artifactId>
            <version>1.4.0</version>
            <executions>                
                <execution>
                    <phase>process-sources</phase>
                    <goals>
                        <goal>replace</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <file>${version.template.file}</file>
                <outputFile>${version.file}</outputFile>
                <replacements>
                    <replacement>
                        <token>@buildnumber@</token>
                        <value>${svn.revision}</value>
                    </replacement>
                    <replacement>
                        <token>@buildtime@</token>
                        <value>${maven.build.timestamp}</value>
                    </replacement>
                    <replacement>
                        <token>@pomversion@</token>
                        <value>${project.version}</value>
                    </replacement>
                </replacements>                        
            </configuration>
      </plugin>
    </plugins>
  </build>
  ...
</project>

The Version.java.template might be:

Version.java.template可能是:

package com.*;

public final class Version {

    public static final String build_number="@buildnumber@";

    public static final String build_time="@buildtime@";

    public static final String pomversion="@pomversion@";

}

#3


14  

This is an old question, but there is another solution that does a great job this perfectly (in the Maven sense): Templating Maven Plugin.

这是一个老问题,但还有另一种解决方案可以很好地完成这项工作(在Maven意义上):Templating Maven插件。

Using this plugin results in the processed Java file being put into the target/generated-sources folder, as you would expect. And it adds the folder under generated-sources to the build path. You will no longer check-in the processed file by mistake.

使用此插件会将处理后的Java文件放入target / generated-sources文件夹中,如您所料。并将生成源下的文件夹添加到构建路径中。您将不再错误地签入已处理的文件。

How to use

如何使用

First put the following under src/main/java-templates/com/foo/bar/Version.java:

首先将以下内容放在src / main / java-templates / com / foo / bar / Version.java下:

package com.foo.bar;
public final class Version {
    public static final String VERSION = "${project.version}";
}

Then add the following to your POM:

然后将以下内容添加到您的POM:

<build>
    <plugins>
    ...
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>templating-maven-plugin</artifactId>
            <version>1.0.0</version>
            <executions>
                <execution>
                    <id>filtering-java-templates</id>
                    <goals>
                        <goal>filter-sources</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    ...
    </plugins>
</build>

The folder target/generated-sources/java-templates is added to the build path by Maven.

文件夹target / generated-sources / java-templates由Maven添加到构建路径中。

#4


11  

Here is another solution that will produce the same as Ralph's own answer, using pom properties filtering and a template file:

这是另一种解决方案,它将使用pom属性过滤和模板文件生成与Ralph自己的答案相同的解决方案:

The template file (VersionJava.template placed in src/main/resources/version):

模板文件(VersionJava.template放在src / main / resources / version中):

package ${ver.package.name};
public final class ${ver.class.name} {
    public static String VERSION="${ver.buildtime}";
}

The pom:

pom:

<properties>
    ...
    <ver.package.dir>com/foo/bar${project.artifactId}</ver.package.dir>
    <ver.package.name>com.foo.bar${project.artifactId}</ver.package.name>
    <ver.class.name>Version</ver.class.name>
    <ver.buildtime>${maven.build.timestamp}</ver.buildtime>
    <ver.template.dir>src/main/resources/version</ver.template.dir>
    <ver.template.file>VersionJava.template</ver.template.file>
</properties>
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <excludes>
                <exclude>version/*</exclude>
            </excludes>
        </resource>
        <resource>
            <directory>${ver.template.dir}</directory>
            <includes>
                <include>*.java</include>
            </includes>
            <filtering>true</filtering>
            <targetPath>${basedir}/src/main/java/${ver.package.dir}</targetPath>
        </resource>
    </resources>        
    <plugins>
        <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <configuration>
                        <tasks>
                            <copy file="${ver.template.dir}/${ver.template.file}" tofile="${ver.template.dir}/${ver.class.name}.java" />
                        </tasks>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
                <execution>
                    <phase>compile</phase>
                    <configuration>
                        <tasks>
                            <delete file="${ver.template.dir}/${ver.class.name}.java" />
                        </tasks>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Now this may seem excessive, but it is extremely versatile, and what I like most about it is that I have the template file in a readable format (rather than echo statements in the pom). This also allows me to modify the version class without having to change the pom

现在这看起来似乎过多,但它非常通用,我最喜欢它的是我有一个可读格式的模板文件(而不是pom中的echo语句)。这也允许我修改版本类而不必更改pom

#5


7  

Based on the answer by @superole. This is a simplified version without the need to set extra properties. Just the project's version is copied into Version.java.

根据@superole的回答。这是一个简化版本,无需设置额外的属性。只需将项目的版本复制到Version.java中。

Put Version.java into src/main/templates:

将Version.java放入src / main / templates中:

package thepackage;

public final class Version {

 public static String VERSION="${project.version}";

}

Instruct maven to replace the tokens in Version.java

指示maven替换Version.java中的标记

<resources>
    <resource>
        <directory>src/main/templates</directory>
        <includes>
            <include>*.java</include>
        </includes>
        <filtering>true</filtering>
        <targetPath>${project.build.directory}/generated-sources/java/thepackage</targetPath>
    </resource>
</resources>

Instruct maven to know generated-sources/java as build path:

指示maven知道generated-sources / java作为构建路径:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>1.8</version>
    <executions>
        <execution>
             <id>add-source</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>add-source</goal>
            </goals>
            <configuration>
                <sources>
                    <source>${project.build.directory}/generated-sources/java/</source>
                </sources>
            </configuration>
        </execution>
    </executions>
</plugin>

Finally, let Eclipse m2e

最后,让Eclipse m2e

  • be aware of the new build path
  • 注意新的构建路径
  • and not to fall into an endless loop build.
  • 而不是陷入无尽的循环构建。

The second point is achieved by disabling using the maven-resources-plugin during the incremental build of eclipse.

第二点是通过在eclipse的增量构建期间禁用maven-resources-plugin来实现的。

<pluginManagement>
    <plugins>
        <plugin>
            <groupId>org.eclipse.m2e</groupId>
            <artifactId>lifecycle-mapping</artifactId>
            <version>1.0.0</version>
            <configuration>
                <lifecycleMappingMetadata>
                    <pluginExecutions>
                        <pluginExecution>
                          <pluginExecutionFilter>
                            <groupId>org.codehaus.mojo</groupId>
                            <artifactId>build-helper-maven-plugin</artifactId>
                            <versionRange>[1.0,)</versionRange>
                            <goals>
                              <goal>parse-version</goal>
                              <goal>add-source</goal>
                              <goal>maven-version</goal>
                              <goal>add-resource</goal>
                              <goal>add-test-resource</goal>
                              <goal>add-test-source</goal>
                            </goals>
                          </pluginExecutionFilter>
                          <action>
                            <execute>
                              <runOnConfiguration>true</runOnConfiguration>
                              <runOnIncremental>true</runOnIncremental>
                            </execute>
                          </action>
                        </pluginExecution>
                        <pluginExecution>
                            <pluginExecutionFilter>
                                <groupId>org.apache.maven.plugins</groupId>
                                <artifactId>maven-resources-plugin</artifactId>
                                <versionRange>[1.0.0,)</versionRange>
                                <goals>
                                    <goal>resources</goal>
                                </goals>
                            </pluginExecutionFilter>
                            <action>
                                <execute>
                                    <runOnConfiguration>true</runOnConfiguration>
                                    <runOnIncremental>false</runOnIncremental>
                                </execute>
                            </action>
                        </pluginExecution>
                    </pluginExecutions>
                </lifecycleMappingMetadata>
            </configuration>
        </plugin>
    </plugins>
</pluginManagement>

thepackage needs to be replaced by your package: Also adjust the targetPath accordingly. I found it easier to set the path in targetpath instead of having many subfolders in src/main/templates.

包装需要由包装替换:还要相应地调整targetPath。我发现在targetpath中设置路径更容易,而不是在src / main / templates中有很多子文件夹。

#6


6  

After more Googling, I came up with this (in the pom.xml):

经过更多谷歌搜索,我想出了这个(在pom.xml中):

<plugins>
  ...
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.3</version>
    <executions>
      <execution>
        <goals>
          <goal>run</goal>
        </goals>
        <phase>generate-sources</phase>
        <configuration>
          <tasks>
            <property name="src.dir" value="${project.build.sourceDirectory}" />
            <property name="package.dir" value="com/foo/bar" />
            <property name="package.name" value="com.foo.bar" />
            <property name="buildtime" value="${maven.build.timestamp}" />

            <echo file="${src.dir}/${package.dir}/Version.java" message="package ${package.name};${line.separator}" />
            <echo file="${src.dir}/${package.dir}/Version.java" append="true" message="public final class Version {${line.separator}" />
            <echo file="${src.dir}/${package.dir}/Version.java" append="true"
              message=" public static String VERSION=&quot;${buildtime}&quot;;${line.separator}" />
            <echo file="${src.dir}/${package.dir}/Version.java" append="true" message="}${line.separator}" />
            <echo message="BUILD ${buildtime}" />
          </tasks>
        </configuration>
      </execution>
    </executions>
  </plugin>
  ...
</plugins>

It seems to work well and produces this Java file:

它似乎运行良好,并生成此Java文件:

package com.foo.bar;
public final class Version {
 public static String VERSION="100318.1211";
}

#7


3  

As suggested by @Romain, you could read the version from a property file (either /META-INF/maven/groupId/artifactId/pom.properties if you can wait until the packaging or roll your own filtered file if you can't or if it doesn't provide everything you need).

正如@Romain所建议的那样,您可以从属性文件中读取版本(/META-INF/maven/groupId/artifactId/pom.properties,如果您可以等到包装或滚动您自己的过滤文件,如果您不能或如果它没有提供你需要的一切)。

And is you want to stick with your actual Version class, then have a look at this thread on the maven users list which is precisely proposing a solution for this (based on the antrun plugin that you'll bind on the generated-sources phase).

你是否想要坚持你的实际版本类,然后看看maven用户列表中的这个线程,它正在为此提出一个解决方案(基于你将在生成源阶段绑定的antrun插件) 。

#8


2  

See http://www.gxdeveloperweb.com/Blogs/Bram-de-Kruijff/Maven-secrets-filtering-sources.htm

见http://www.gxdeveloperweb.com/Blogs/Bram-de-Kruijff/Maven-secrets-filtering-sources.htm

#9


2  

I'm doing it using the Maven WAR Plugin adding information to the MANIFEST.MF file and later reading this MANIFEST.MF file in Java:

我正在使用Maven WAR插件向MANIFEST.MF文件添加信息,然后在Java中读取这个MANIFEST.MF文件:

     <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.6</version>
        <configuration>
           <archive>
              <manifest>
                 <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                 <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
              </manifest>
              <manifestEntries>
                 <Build-Time>${maven.build.timestamp}</Build-Time>
              </manifestEntries>
           </archive>
        </configuration>
     </plugin>

This configuration generates the following MANIFEST.MF file:

此配置生成以下MANIFEST.MF文件:

Manifest-Version: 1.0
Implementation-Title: MyApp
Implementation-Version: 2.11.0-SNAPSHOT
Built-By: niestroj
Specification-Title: MyApp
Implementation-Vendor-Id: com.mycompany
Build-Time: 2017-01-09 15:30
Created-By: Apache Maven 3.0.5
Build-Jdk: 1.8.0_40
Specification-Version: 2.11

And later i'm reading this in Java like this:

后来我用Java读这个:

  try {
     Manifest manifest = new Manifest(getServletContext().getResourceAsStream("/META-INF/MANIFEST.MF"));
     Attributes attributes = manifest.getMainAttributes();
     attributes.getValue("Implementation-Version");
     attributes.getValue("Build-Time");
  } catch (IOException ex) {
     LOGGER.debug("Error reading manifest file information", ex);
  }

#10


1  

The standard way to do just that with very few lines of XML code is now to use the templating-maven-plugin.

使用极少数XML代码行的标准方法现在使用templating-maven-plugin。

See my answer in Filtering source code in Maven

请参阅我在Maven中过滤源代码中的答案

In general, the Maven way is to describe what you want to do. Then figure how. When how requires tens or hundreds of lines of XML, either find the right plugin that does that, or write it. That was the rationale that created the templating-maven-plugin :-).

一般来说,Maven的方式是描述你想要做什么。然后想办法。当需要数十行或数百行XML时,要么找到正确的插件,要么编写它。这就是创建模板-maven-plugin的基本原理:-)。

#1


76  

I don't think this is the good way to solve this kind of issue.

我不认为这是解决这类问题的好方法。

A better way is to put the version information in a properties file that will be read by your Java program:

更好的方法是将版本信息放在Java程序将读取的属性文件中:

Your properties file will contain the following line:

您的属性文件将包含以下行:

myapp.version=${project.version}

Then, in your pom.xml, indicate that the file will be filtered by Maven :

然后,在您的pom.xml中,指示该文件将由Maven过滤:

<resources>
    <resource>
        <directory>the/directory/that/contains/your/properties/file</directory>
        <filtering>true</filtering>
    </resource>
</resources>

When Maven will build your application, it will replace all ${...} by their value. By default, ${project.version} defines the version of the pom.xml (i.e. the value of the <version> tag).

当Maven构建您的应用程序时,它将用它们的值替换所有$ {...}。默认情况下,$ {project.version}定义pom.xml的版本(即 标记的值)。

Then, in your Java code, you will just need to load the properties file and retrieve the myApp.version property value.

然后,在Java代码中,您只需要加载属性文件并检索myApp.version属性值。

Note that you can use the Build Number plugin to set something more "complex" than just your current version (for example if you want to put the build time in your property).

请注意,您可以使用Build Number插件设置比当前版本更“复杂”的内容(例如,如果您想将构建时间放在属性中)。

#2


26  

You can also use maven-replacer-plugin if you feel ant is a little bit ugly: The pom enrty might be:

如果你觉得蚂蚁有点难看,你也可以使用maven-replacer-plugin:pom enrty可能是:

<project>
  ...
  <properties>
    <version.template.file>src/main/java/com/*Version.java.template</version.template.file>
<version.file>src/main/java/com/*/Version.java</version.file>
  </properties>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>com.google.code.maven-replacer-plugin</groupId>
            <artifactId>maven-replacer-plugin</artifactId>
            <version>1.4.0</version>
            <executions>                
                <execution>
                    <phase>process-sources</phase>
                    <goals>
                        <goal>replace</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <file>${version.template.file}</file>
                <outputFile>${version.file}</outputFile>
                <replacements>
                    <replacement>
                        <token>@buildnumber@</token>
                        <value>${svn.revision}</value>
                    </replacement>
                    <replacement>
                        <token>@buildtime@</token>
                        <value>${maven.build.timestamp}</value>
                    </replacement>
                    <replacement>
                        <token>@pomversion@</token>
                        <value>${project.version}</value>
                    </replacement>
                </replacements>                        
            </configuration>
      </plugin>
    </plugins>
  </build>
  ...
</project>

The Version.java.template might be:

Version.java.template可能是:

package com.*;

public final class Version {

    public static final String build_number="@buildnumber@";

    public static final String build_time="@buildtime@";

    public static final String pomversion="@pomversion@";

}

#3


14  

This is an old question, but there is another solution that does a great job this perfectly (in the Maven sense): Templating Maven Plugin.

这是一个老问题,但还有另一种解决方案可以很好地完成这项工作(在Maven意义上):Templating Maven插件。

Using this plugin results in the processed Java file being put into the target/generated-sources folder, as you would expect. And it adds the folder under generated-sources to the build path. You will no longer check-in the processed file by mistake.

使用此插件会将处理后的Java文件放入target / generated-sources文件夹中,如您所料。并将生成源下的文件夹添加到构建路径中。您将不再错误地签入已处理的文件。

How to use

如何使用

First put the following under src/main/java-templates/com/foo/bar/Version.java:

首先将以下内容放在src / main / java-templates / com / foo / bar / Version.java下:

package com.foo.bar;
public final class Version {
    public static final String VERSION = "${project.version}";
}

Then add the following to your POM:

然后将以下内容添加到您的POM:

<build>
    <plugins>
    ...
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>templating-maven-plugin</artifactId>
            <version>1.0.0</version>
            <executions>
                <execution>
                    <id>filtering-java-templates</id>
                    <goals>
                        <goal>filter-sources</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    ...
    </plugins>
</build>

The folder target/generated-sources/java-templates is added to the build path by Maven.

文件夹target / generated-sources / java-templates由Maven添加到构建路径中。

#4


11  

Here is another solution that will produce the same as Ralph's own answer, using pom properties filtering and a template file:

这是另一种解决方案,它将使用pom属性过滤和模板文件生成与Ralph自己的答案相同的解决方案:

The template file (VersionJava.template placed in src/main/resources/version):

模板文件(VersionJava.template放在src / main / resources / version中):

package ${ver.package.name};
public final class ${ver.class.name} {
    public static String VERSION="${ver.buildtime}";
}

The pom:

pom:

<properties>
    ...
    <ver.package.dir>com/foo/bar${project.artifactId}</ver.package.dir>
    <ver.package.name>com.foo.bar${project.artifactId}</ver.package.name>
    <ver.class.name>Version</ver.class.name>
    <ver.buildtime>${maven.build.timestamp}</ver.buildtime>
    <ver.template.dir>src/main/resources/version</ver.template.dir>
    <ver.template.file>VersionJava.template</ver.template.file>
</properties>
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <excludes>
                <exclude>version/*</exclude>
            </excludes>
        </resource>
        <resource>
            <directory>${ver.template.dir}</directory>
            <includes>
                <include>*.java</include>
            </includes>
            <filtering>true</filtering>
            <targetPath>${basedir}/src/main/java/${ver.package.dir}</targetPath>
        </resource>
    </resources>        
    <plugins>
        <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <configuration>
                        <tasks>
                            <copy file="${ver.template.dir}/${ver.template.file}" tofile="${ver.template.dir}/${ver.class.name}.java" />
                        </tasks>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
                <execution>
                    <phase>compile</phase>
                    <configuration>
                        <tasks>
                            <delete file="${ver.template.dir}/${ver.class.name}.java" />
                        </tasks>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Now this may seem excessive, but it is extremely versatile, and what I like most about it is that I have the template file in a readable format (rather than echo statements in the pom). This also allows me to modify the version class without having to change the pom

现在这看起来似乎过多,但它非常通用,我最喜欢它的是我有一个可读格式的模板文件(而不是pom中的echo语句)。这也允许我修改版本类而不必更改pom

#5


7  

Based on the answer by @superole. This is a simplified version without the need to set extra properties. Just the project's version is copied into Version.java.

根据@superole的回答。这是一个简化版本,无需设置额外的属性。只需将项目的版本复制到Version.java中。

Put Version.java into src/main/templates:

将Version.java放入src / main / templates中:

package thepackage;

public final class Version {

 public static String VERSION="${project.version}";

}

Instruct maven to replace the tokens in Version.java

指示maven替换Version.java中的标记

<resources>
    <resource>
        <directory>src/main/templates</directory>
        <includes>
            <include>*.java</include>
        </includes>
        <filtering>true</filtering>
        <targetPath>${project.build.directory}/generated-sources/java/thepackage</targetPath>
    </resource>
</resources>

Instruct maven to know generated-sources/java as build path:

指示maven知道generated-sources / java作为构建路径:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>1.8</version>
    <executions>
        <execution>
             <id>add-source</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>add-source</goal>
            </goals>
            <configuration>
                <sources>
                    <source>${project.build.directory}/generated-sources/java/</source>
                </sources>
            </configuration>
        </execution>
    </executions>
</plugin>

Finally, let Eclipse m2e

最后,让Eclipse m2e

  • be aware of the new build path
  • 注意新的构建路径
  • and not to fall into an endless loop build.
  • 而不是陷入无尽的循环构建。

The second point is achieved by disabling using the maven-resources-plugin during the incremental build of eclipse.

第二点是通过在eclipse的增量构建期间禁用maven-resources-plugin来实现的。

<pluginManagement>
    <plugins>
        <plugin>
            <groupId>org.eclipse.m2e</groupId>
            <artifactId>lifecycle-mapping</artifactId>
            <version>1.0.0</version>
            <configuration>
                <lifecycleMappingMetadata>
                    <pluginExecutions>
                        <pluginExecution>
                          <pluginExecutionFilter>
                            <groupId>org.codehaus.mojo</groupId>
                            <artifactId>build-helper-maven-plugin</artifactId>
                            <versionRange>[1.0,)</versionRange>
                            <goals>
                              <goal>parse-version</goal>
                              <goal>add-source</goal>
                              <goal>maven-version</goal>
                              <goal>add-resource</goal>
                              <goal>add-test-resource</goal>
                              <goal>add-test-source</goal>
                            </goals>
                          </pluginExecutionFilter>
                          <action>
                            <execute>
                              <runOnConfiguration>true</runOnConfiguration>
                              <runOnIncremental>true</runOnIncremental>
                            </execute>
                          </action>
                        </pluginExecution>
                        <pluginExecution>
                            <pluginExecutionFilter>
                                <groupId>org.apache.maven.plugins</groupId>
                                <artifactId>maven-resources-plugin</artifactId>
                                <versionRange>[1.0.0,)</versionRange>
                                <goals>
                                    <goal>resources</goal>
                                </goals>
                            </pluginExecutionFilter>
                            <action>
                                <execute>
                                    <runOnConfiguration>true</runOnConfiguration>
                                    <runOnIncremental>false</runOnIncremental>
                                </execute>
                            </action>
                        </pluginExecution>
                    </pluginExecutions>
                </lifecycleMappingMetadata>
            </configuration>
        </plugin>
    </plugins>
</pluginManagement>

thepackage needs to be replaced by your package: Also adjust the targetPath accordingly. I found it easier to set the path in targetpath instead of having many subfolders in src/main/templates.

包装需要由包装替换:还要相应地调整targetPath。我发现在targetpath中设置路径更容易,而不是在src / main / templates中有很多子文件夹。

#6


6  

After more Googling, I came up with this (in the pom.xml):

经过更多谷歌搜索,我想出了这个(在pom.xml中):

<plugins>
  ...
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.3</version>
    <executions>
      <execution>
        <goals>
          <goal>run</goal>
        </goals>
        <phase>generate-sources</phase>
        <configuration>
          <tasks>
            <property name="src.dir" value="${project.build.sourceDirectory}" />
            <property name="package.dir" value="com/foo/bar" />
            <property name="package.name" value="com.foo.bar" />
            <property name="buildtime" value="${maven.build.timestamp}" />

            <echo file="${src.dir}/${package.dir}/Version.java" message="package ${package.name};${line.separator}" />
            <echo file="${src.dir}/${package.dir}/Version.java" append="true" message="public final class Version {${line.separator}" />
            <echo file="${src.dir}/${package.dir}/Version.java" append="true"
              message=" public static String VERSION=&quot;${buildtime}&quot;;${line.separator}" />
            <echo file="${src.dir}/${package.dir}/Version.java" append="true" message="}${line.separator}" />
            <echo message="BUILD ${buildtime}" />
          </tasks>
        </configuration>
      </execution>
    </executions>
  </plugin>
  ...
</plugins>

It seems to work well and produces this Java file:

它似乎运行良好,并生成此Java文件:

package com.foo.bar;
public final class Version {
 public static String VERSION="100318.1211";
}

#7


3  

As suggested by @Romain, you could read the version from a property file (either /META-INF/maven/groupId/artifactId/pom.properties if you can wait until the packaging or roll your own filtered file if you can't or if it doesn't provide everything you need).

正如@Romain所建议的那样,您可以从属性文件中读取版本(/META-INF/maven/groupId/artifactId/pom.properties,如果您可以等到包装或滚动您自己的过滤文件,如果您不能或如果它没有提供你需要的一切)。

And is you want to stick with your actual Version class, then have a look at this thread on the maven users list which is precisely proposing a solution for this (based on the antrun plugin that you'll bind on the generated-sources phase).

你是否想要坚持你的实际版本类,然后看看maven用户列表中的这个线程,它正在为此提出一个解决方案(基于你将在生成源阶段绑定的antrun插件) 。

#8


2  

See http://www.gxdeveloperweb.com/Blogs/Bram-de-Kruijff/Maven-secrets-filtering-sources.htm

见http://www.gxdeveloperweb.com/Blogs/Bram-de-Kruijff/Maven-secrets-filtering-sources.htm

#9


2  

I'm doing it using the Maven WAR Plugin adding information to the MANIFEST.MF file and later reading this MANIFEST.MF file in Java:

我正在使用Maven WAR插件向MANIFEST.MF文件添加信息,然后在Java中读取这个MANIFEST.MF文件:

     <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.6</version>
        <configuration>
           <archive>
              <manifest>
                 <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                 <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
              </manifest>
              <manifestEntries>
                 <Build-Time>${maven.build.timestamp}</Build-Time>
              </manifestEntries>
           </archive>
        </configuration>
     </plugin>

This configuration generates the following MANIFEST.MF file:

此配置生成以下MANIFEST.MF文件:

Manifest-Version: 1.0
Implementation-Title: MyApp
Implementation-Version: 2.11.0-SNAPSHOT
Built-By: niestroj
Specification-Title: MyApp
Implementation-Vendor-Id: com.mycompany
Build-Time: 2017-01-09 15:30
Created-By: Apache Maven 3.0.5
Build-Jdk: 1.8.0_40
Specification-Version: 2.11

And later i'm reading this in Java like this:

后来我用Java读这个:

  try {
     Manifest manifest = new Manifest(getServletContext().getResourceAsStream("/META-INF/MANIFEST.MF"));
     Attributes attributes = manifest.getMainAttributes();
     attributes.getValue("Implementation-Version");
     attributes.getValue("Build-Time");
  } catch (IOException ex) {
     LOGGER.debug("Error reading manifest file information", ex);
  }

#10


1  

The standard way to do just that with very few lines of XML code is now to use the templating-maven-plugin.

使用极少数XML代码行的标准方法现在使用templating-maven-plugin。

See my answer in Filtering source code in Maven

请参阅我在Maven中过滤源代码中的答案

In general, the Maven way is to describe what you want to do. Then figure how. When how requires tens or hundreds of lines of XML, either find the right plugin that does that, or write it. That was the rationale that created the templating-maven-plugin :-).

一般来说,Maven的方式是描述你想要做什么。然后想办法。当需要数十行或数百行XML时,要么找到正确的插件,要么编写它。这就是创建模板-maven-plugin的基本原理:-)。