IT TIP

Maven에서 Version.java 파일 생성

itqueen 2021. 1. 9. 11:12
반응형

Maven에서 Version.java 파일 생성


Ant 스크립트를 사용하여 빌드 한 Java 프로젝트가 있습니다. 프로젝트를 Maven으로 변환하려고합니다.

태스크 중 하나는 다음과 같이 컴파일 타임 스탬프의 정적 문자열 표현을 포함하는 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>

소스 생성 또는 다른 간단한 방법을 사용하여 Maven에서 비슷한 작업을 수행 할 수 있습니까?


나는 이것이 이런 종류의 문제를 해결하는 좋은 방법이라고 생각하지 않습니다.

더 나은 방법은 propertiesJava 프로그램에서 읽을 파일에 버전 정보를 넣는 것입니다.

속성 파일에는 다음 줄이 포함됩니다.

myapp.version=${project.version}

그런 다음 pom.xml에서 파일이 Maven에 의해 필터링 됨을 나타냅니다 .

<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 플러그인사용 하여 현재 버전보다 더 "복잡한"것을 설정할 수 있습니다 (예 : 속성에 빌드 시간을 입력하려는 경우).


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>

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에 의해 빌드 경로에 추가됩니다.


다음은 pom 속성 필터링 및 템플릿 파일을 사용하여 Ralph의 자체 답변과 동일한 결과를 생성하는 또 다른 솔루션입니다.

템플릿 파일 (src / main / resources / version에있는 VersionJava.template) :

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

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>

이제 이것은 과도하게 보일 수 있지만 매우 다재다능하며 내가 가장 좋아하는 것은 (pom의 echo 문이 아닌) 읽을 수있는 형식의 템플릿 파일이 있다는 것입니다. 이렇게하면 pom을 변경하지 않고도 버전 클래스를 수정할 수 있습니다.


더 많은 인터넷 검색 후, 나는 이것을 (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 파일을 생성합니다.

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

@superole의 답변을 기반으로 합니다 . 이것은 추가 속성을 설정할 필요가없는 단순화 된 버전입니다. 프로젝트의 버전 만 Version.java에 복사됩니다.

넣어 Version.javasrc/main/templates:

package thepackage;

public final class Version {

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

}

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>

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>

마지막으로 Eclipse m2e

  • 새로운 빌드 경로를 알고 있어야합니다.
  • 끝없는 루프 빌드에 빠지지 않습니다.

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

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


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

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


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:

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

  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);
  }

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


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

See my answer in Filtering source code in 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 :-).

ReferenceURL : https://stackoverflow.com/questions/2469922/generate-a-version-java-file-in-maven

반응형