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="${buildtime}";${line.separator}" />
<echo file="src/${package.dir}/Version.Java" append="true" message="}${line.separator}" />
<echo message="BUILD ${buildtime}" />
</target>
Generate-sources、またはその他の簡単な方法を使用して、Mavenで同様のことを行うことは可能ですか?
さらにグーグルで調べた後、私はこれを(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="${buildtime}";${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";
}
これがこの種の問題を解決する良い方法だとは思いません。
より良い方法は、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 を使用して、現在のバージョンよりも「複雑」なものを設定できることに注意してください(たとえば、ビルド時間をプロパティに入れたい場合)。
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@";
}
これは古い質問ですが、別の解決策があります 素晴らしい仕事 これは完全に(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によってビルドパスに追加されます。
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を変更せずにバージョンクラスを変更することもできます
@ superoleによる答え に基づいています。これは、追加のプロパティを設定する必要のない簡易バージョンです。プロジェクトのバージョンだけがVersion.Javaにコピーされます。
Version.Java
をsrc/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
にパスを設定する方が簡単だとわかりました。
@Romainが示唆するように、プロパティファイルからバージョンを読み取ることができます(パッケージ化まで待機できる場合は/META-INF/maven/groupId/artifactId/pom.properties
、必要なものがすべて提供されない場合、またはパッケージ化できない場合は独自のフィルターファイルをロールします)。
そして、あなたは実際のVersion
クラスに固執し、それから( this thread を見てください)これは(antrunプラグインに基づいて)これに対する解決策を正確に提案していますgenerated-sources
フェーズにバインドします)。
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);
}
ごく少数のXMLコードでこれを行う標準的な方法は、現在、templating-maven-pluginを使用することです。
Mavenのソースコードのフィルタリング で私の答えを参照してください
一般に、Mavenの方法は、やりたいことをwhatと記述することです。 Thenfigurehow。数十行から数百行のXMLが必要な場合、それを行う適切なプラグインを見つけるか、それを記述します。これが、templating-maven-pluginを作成した理由です:-)。