57 votes

Générer un fichier Version.java dans Maven

J'ai un projet Java que je construis à l'aide d'un script Ant. J'essaie de convertir le projet en Maven.

L'une des tâches génère un fichier source Java appelé Version.java qui contient une représentation sous forme de chaîne statique de l'horodatage de compilation, comme suit:

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

La tâche Ant est très simple:

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

Est-il possible de faire quelque chose de similaire dans Maven, en utilisant generate-sources ou une autre méthode simple?

79voto

romaintaz Points 32120

Je ne pense pas que ce soit la bonne façon de résoudre ce type de problème.

Une meilleure méthode consiste à mettre les informations de la version properties le fichier qui sera lu par votre programme Java:

Les propriétés de votre fichier contient la ligne suivante:

myapp.version=${project.version}

Puis, dans votre pom.xml, indiquent que le fichier sera filtré par Maven :

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

Lorsque Maven sera de construire votre application, il remplace tous ${...} de leur valeur. Par défaut, ${project.version} définit la version de l' pom.xml (soit la valeur de l' <version> tag).

Puis, dans votre code Java, vous aurez juste besoin de charger l' properties le fichier et de récupérer l' myApp.version de la valeur de propriété.

Notez que vous pouvez utiliser le Numéro de version du plugin pour définir quelque chose de plus "complexe" que votre version actuelle (par exemple si vous voulez mettre l'accumulation de temps dans votre propriété).

28voto

spupek Points 217

Vous pouvez également utiliser maven-replacer-plugin si vous pensez que la fourmi est un peu laide: le pompon pourrait être:

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

Le Version.java.template pourrait être:

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

}
 

12voto

Superole Points 401

Voici une autre solution qui produira le même que Ralph sa propre réponse, à l'aide de pom propriétés de filtrage et d'un fichier de modèle:

Le fichier de modèle (VersionJava.modèle placé dans src/main/resources/version):

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

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

Maintenant, cela peut sembler excessif, mais il est extrêmement polyvalent, et ce que j'aime le plus à ce sujet c'est que j'ai le fichier de modèle dans un format lisible (plutôt que de l'écho des déclarations dans le pom). Cela me permet également de modifier la version de classe sans avoir à modifier le pom

10voto

Ralph Points 9405

Après plus de recherches sur Google, je suis venu avec ceci (dans le 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>
 

Il semble bien fonctionner et produit ce fichier Java:

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

9voto

koppor Points 2066

Basé sur la réponse de @superole. C'est une version simplifiée, sans la nécessité de définir des propriétés supplémentaires. Le projet de version est copié dans Version.java.

Mettre Version.java en src/main/templates:

package thepackage;

public final class Version {

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

}

Instruire maven pour remplacer les jetons dans 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>

Instruire maven savoir generated-sources/java comme build path:

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

Enfin, permettez-Eclipse m2e

  • être conscient de la construction de la nouvelle voie
  • et ne pas tomber dans une boucle sans fin de construction.

Le deuxième point est atteint par la désactivation de l'aide de l' maven-ressources-plugin lors de l'augmentation de la construction d'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 doit être remplacé par votre package: Également régler l' targetPath en conséquence. Je l'ai trouvé plus facile de définir le chemin d'accès en targetpath au lieu d'avoir plusieurs sous-dossiers, en src/main/templates.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X