在Maven中生成Version.java文件

Ral*_*lph 54 java maven-2 code-generation

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

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

package com.foo.bar;
public final class Version {
 public static String VERSION="100301.1046";
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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

Rom*_*las 78

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

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

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

myapp.version=${project.version}
Run Code Online (Sandbox Code Playgroud)

然后,在你的pom.xml,表明该文件将由Maven 过滤:

<resources>
    <resource>
        <directory>the/directory/that/contains/your/properties/file</directory>
        <filtering>true</filtering>
    </resource>
</resources>
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 为什么不是解决它的好方法?我有多个具有不相交的属性文件集的模块.我认为存储到多个属性文件是错误的方法. (4认同)

小智 27

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

<project>
  ...
  <properties>
    <version.template.file>src/main/java/com/stackoverflowVersion.java.template</version.template.file>
<version.file>src/main/java/com/stackoverflow/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>
Run Code Online (Sandbox Code Playgroud)

Version.java.template可能是:

package com.stackoverflow;

public final class Version {

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

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

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

}
Run Code Online (Sandbox Code Playgroud)

  • 更好地使用“生成源”阶段 (2认同)

veg*_*4me 16

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

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

如何使用

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

package com.foo.bar;
public final class Version {
    public static final String VERSION = "${project.version}";
}
Run Code Online (Sandbox Code Playgroud)

然后将以下内容添加到您的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>
Run Code Online (Sandbox Code Playgroud)

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


Sup*_*ole 12

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

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

package ${ver.package.name};
public final class ${ver.class.name} {
    public static String VERSION="${ver.buildtime}";
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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


Ral*_*lph 8

经过更多谷歌搜索,我想出了这个(在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>
Run Code Online (Sandbox Code Playgroud)

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

package com.foo.bar;
public final class Version {
 public static String VERSION="100318.1211";
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常糟糕的解决方案.更好地使用romaintaz给出的解决方案.为这种东西生成源代码会导致不必要的编译,因为每次重新创建java文件时都会触发一系列编译.请你自己和你的同事一个忙,不要这样做! (9认同)
  • 我正在寻找一种在“webapp”根目录中创建文本文件 version.txt 的解决方案,我想这是最好的解决方案。 (2认同)

kop*_*por 8

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

Version.javasrc/main/templates:

package thepackage;

public final class Version {

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

}
Run Code Online (Sandbox Code Playgroud)

指示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>
Run Code Online (Sandbox Code Playgroud)

指示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>
Run Code Online (Sandbox Code Playgroud)

最后,让Eclipse m2e

  • 注意新的构建路径
  • 而不是陷入无尽的循环构建.

第二点是通过在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>
Run Code Online (Sandbox Code Playgroud)

thepackage需要由您的包裹替换:也相应调整targetPath.我发现设置路径更容易,targetpath而不是有很多子文件夹src/main/templates.

  • 这太棒了. (2认同)