web-dev-qa-db-ja.com

MavenでVersion.Javaファイルを生成する

Antスクリプトを使用してビルドするJavaプロジェクトがあります。プロジェクトをMavenに変換しようとしています。

タスクの1つは、次のように、コンパイルタイムスタンプの静的な文字列表現を含むVersion.Javaという名前のJavaソースファイルを生成します。

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

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>

Generate-sources、またはその他の簡単な方法を使用して、Mavenで同様のことを行うことは可能ですか?

54
Ralph

さらにグーグルで調べた後、私はこれを(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>

それはうまくいくようで、これを生成しますJava file:

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

これがこの種の問題を解決する良い方法だとは思いません。

より良い方法は、Javaプログラムによって読み取られるpropertiesファイルにバージョン情報を入れることです:

プロパティファイルには次の行が含まれます。

myapp.version=${project.version}

次に、pom.xmlで、ファイルがMavenによって filtered になることを示します。

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

Mavenがアプリケーションをビルドするとき、すべての${...}をその値で置き換えます。デフォルトでは、${project.version}pom.xmlのバージョン(つまり<version>タグの値)を定義します。

次に、Javaコードで、propertiesファイルをロードし、myApp.versionプロパティ値を取得する必要があります。

Build Number plugin を使用して、現在のバージョンよりも「複雑」なものを設定できることに注意してください(たとえば、ビルド時間をプロパティに入れたい場合)。

78
Romain Linsolas

maven-replacer-plugin antが少しいと感じる場合: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>

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@";

}
27
spupek

これは古い質問ですが、別の解決策があります 素晴らしい仕事 これは完全に(Mavenの意味で): Templating Maven Plugin

このプラグインを使用すると、処理済みの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}";
}

次に、以下を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>

フォルダーtarget/generated-sources/Java-templatesは、Mavenによってビルドパスに追加されます。

15
vegemite4me

Ralph自身の答えと同じものを生成する別のソリューションを次に示します。pomプロパティフィルタリングとテンプレートファイルを使用します。

テンプレートファイル(src/main/resources/versionに配置されているVersionJava.template):

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

ポンポン:

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

これは過剰に思えるかもしれませんが、非常に用途が広く、私が一番気に入っているのは、(pom内のechoステートメントではなく)読み取り可能な形式のテンプレートファイルがあることです。これにより、pomを変更せずにバージョンクラスを変更することもできます

12
Superole

@ superoleによる答え に基づいています。これは、追加のプロパティを設定する必要のない簡易バージョンです。プロジェクトのバージョンだけがVersion.Javaにコピーされます。

Version.Javasrc/main/templatesに入れます:

package thepackage;

public final class Version {

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

}

Version.Javaのトークンを置き換えるようにMavenに指示します

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

ビルドパスとしてgenerated-sources/Javaを知るようにmavenに指示します。

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

最後に、Eclipse m2e

  • 新しいビルドパスに注意してください
  • 無限ループビルドに陥らないようにします。

2番目のポイントは、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はパッケージに置き換える必要があります:targetPathもそれに応じて調整します。 src/main/templatesに多くのサブフォルダーを持たせる代わりに、targetpathにパスを設定する方が簡単だとわかりました。

8
koppor

@Romainが示唆するように、プロパティファイルからバージョンを読み取ることができます(パッケージ化まで待機できる場合は/META-INF/maven/groupId/artifactId/pom.properties、必要なものがすべて提供されない場合、またはパッケージ化できない場合は独自のフィルターファイルをロールします)。

そして、あなたは実際のVersionクラスに固執し、それから( this thread を見てください)これは(antrunプラグインに基づいて)これに対する解決策を正確に提案していますgenerated-sourcesフェーズにバインドします)。

3
Pascal Thivent
2
Laurent Pireyn

Maven WARプラグインMANIFEST.MF ファイルに情報を追加し、後でこのMANIFEST.MFファイルをJavaで読み込んで使用しています:

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

この構成では、次の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

そして後で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);
  }
2
Robert Niestroj

ごく少数のXMLコードでこれを行う標準的な方法は、現在、templating-maven-pluginを使用することです。

Mavenのソースコードのフィルタリング で私の答えを参照してください

一般に、Mavenの方法は、やりたいことをwhatと記述することです。 Thenfigurehow。数十行から数百行のXMLが必要な場合、それを行う適切なプラグインを見つけるか、それを記述します。これが、templating-maven-pluginを作成した理由です:-)。

1
Baptiste Mathus