Propriété Maven2 qui indique le répertoire parent

j'ai un projet multi-modules, comme celui-ci:

main-project/
    module1/
    module2/
        sub-module1/
        sub-module2/
        sub-module3/
        ...
    module3/
    module4/
    ...

je dois définir un ensemble de propriétés (qui dépendent de l'environnement sur lequel je veux publier mon projet) dans Maven2. Je n'utiliserai pas <properties> car il y a beaucoup de propriétés... Ainsi, j'utilise le propriétés Maven2 plugin .

les fichiers de propriétés sont situés dans le répertoire main-project/ . Comment puis-je définir le répertoire correct dans l' principal pom.xml, afin de préciser aux enfants où trouver le fichier de propriétés?

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>properties-maven-plugin</artifactId>
    <version>1.0-alpha-1</version>
    <executions>
        <execution>
            <phase>initialize</phase>
            <goals>
                <goal>read-project-properties</goal>
            </goals>
            <configuration>
                <files>
                    <file>???/env_${env}.properties</file>
                </files>
            </configuration>
        </execution>
    </executions>
</plugin>

si je mets seulement <file>env_${env}.properties</file> , alors quand Maven2 compile le premier module, il ne trouvera pas le fichier main-project/env_dev.properties . Si je mets <file>../env_${env}.properties</file> , alors une erreur sera soulevée au niveau parent, ou à n'importe quel niveau de sous-module...

86
demandé sur Rich Seller 2009-06-18 16:34:53

18 réponses

essayez de définir une propriété dans chaque pom pour trouver le répertoire principal du projet.

Dans le parent:

<properties>
    <main.basedir>${project.basedir}</main.basedir>
</properties>

dans les enfants:

<properties>
    <main.basedir>${project.parent.basedir}</main.basedir>
</properties>

dans les petits-enfants:

<properties>
    <main.basedir>${project.parent.parent.basedir}</main.basedir>
</properties>
134
répondu Clay 2009-06-19 18:34:45

j'ai trouvé une solution pour résoudre mon problème: je recherche les fichiers de propriétés en utilisant le plugin Groovy Maven.

comme mon fichier de propriétés est nécessairement dans le répertoire courant, in ../ ou dans ../.., J'ai écrit un petit code de Groovy qui vérifie ces trois dossiers.

Voici l'extrait de mon pompon.xml:

<!-- Use Groovy to search the location of the properties file. -->
<plugin>
    <groupId>org.codehaus.groovy.maven</groupId>
    <artifactId>gmaven-plugin</artifactId>
    <version>1.0-rc-5</version>
    <executions>
        <execution>
            <phase>validate</phase>
            <goals>
                <goal>execute</goal>
            </goals>
            <configuration>
                <source>
                    import java.io.File;
                    String p = project.properties['env-properties-file'];
                    File f = new File(p); 
                    if (!f.exists()) {
                        f = new File("../" + p);
                        if (!f.exists()) {
                            f = new File("../../" + p);
                        }
                    }
                    project.properties['env-properties-file-by-groovy'] = f.getAbsolutePath();
            </source>
            </configuration>
        </execution>
    </executions>
</plugin>
<!-- Now, I can load the properties file using the new 'env-properties-file-by-groovy' property. -->
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>properties-maven-plugin</artifactId>
    <version>1.0-alpha-1</version>
    <executions>
        <execution>
            <phase>initialize</phase>
            <goals>
                <goal>read-project-properties</goal>
            </goals>
            <configuration>
                <files>
                    <file>${env-properties-file-by-groovy}</file>
                </files>
            </configuration>
        </execution>
    </executions>
</plugin>

ça marche, mais je n'aime pas ça.

Donc, si vous avez une meilleure solution, n' n'hésitez pas à poster!

14
répondu romaintaz 2009-06-19 09:22:14

Donc, le problème que je vois c'est que vous ne pouvez pas obtenir le chemin absolu vers le répertoire parent dans maven.

j'ai entendu parler de cela comme un anti-modèle , mais pour chaque anti-modèle Il ya réelle, légitime cas d'utilisation pour elle, et je suis malade de maven me dire que je ne peux que suivre leurs modèles.

donc le travail autour que j'ai trouvé était d'utiliser antrun. Essayez ça dans la pom-pom girl.xml:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.7</version>
    <executions>
        <execution>
            <id>getMainBaseDir</id>
            <phase>validate</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <exportAntProperties>true</exportAntProperties>
                <target>
                    <!--Adjust the location below to your directory structure -->
                    <property name="main.basedir" location="./.." />
                    <echo message="main.basedir=${main.basedir}"/>
                </target>
            </configuration>
        </execution>
    </executions>
</plugin>

si vous lancez mvn verify vous devriez voir quelque chose comme ceci:

main:
     [echo] main.basedir=C:\src\parent.project.dir.name

vous pouvez alors utiliser ${main.basedir} dans n'importe lequel des autres plugins, etc. M'a fallu du temps pour comprendre cela, donc espérons que cela aide quelqu'un d'autre.

11
répondu Jared 2012-08-29 19:07:59

Utiliser directory-maven-plugin avec l'annuaire de l'objectif .

contrairement à d'autres suggestions:

  • cette solution fonctionne pour les projets multi-modules.
  • il fonctionne si vous construisez l'ensemble du projet ou un sous-module.
  • cela fonctionne que vous exécutiez maven à partir du dossier racine ou d'un sous-module.
  • il n'est pas nécessaire de définir une propriété relative path dans chaque et chaque sous-module de!

le plugin vous permet de définir une propriété de votre choix sur le chemin absolu de l'un des modules du projet. Dans mon cas, je l'ai réglé sur le module racine... Dans mon projet root pom:

<plugin>
    <groupId>org.commonjava.maven.plugins</groupId>
    <artifactId>directory-maven-plugin</artifactId>
    <version>0.1</version>
    <executions>
        <execution>
            <id>directories</id>
            <goals>
                <goal>directory-of</goal>
            </goals>
            <phase>initialize</phase>
            <configuration>
                <property>myproject.basedir</property>
                <project>
                    <groupId>com.my.domain</groupId>
                    <artifactId>my-root-artifact</artifactId>
                </project>
            </configuration>
        </execution>
    </executions>
</plugin>

à partir de là, $myproject.basedir} dans n'importe quel sous-module, pom a toujours le chemin du module racine du projet. Et bien sûr, vous pouvez définir la propriété de n'importe quel module, pas seulement la racine...

11
répondu sparkyd 2018-09-07 07:37:43

dans mon cas, ça marche comme ça:

...
<properties>
  <main_dir>${project.parent.relativePath}/..</main_dir>
</properties>
...

<plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>properties-maven-plugin</artifactId>
        <version>1.0-alpha-1</version>
        <executions>
          <execution>
            <phase>initialize</phase>
            <goals>
              <goal>read-project-properties</goal>
            </goals>
            <configuration>
              <files>
                 <file>${main_dir}/maven_custom.properties</file>
              </files>
            </configuration>
          </execution>
        </executions>
</plugin>
6
répondu user1774153 2015-07-07 07:31:03

le petit profil suivant a fonctionné pour moi. J'avais besoin d'une telle configuration pour CheckStyle, que j'ai mis dans le répertoire config dans la racine du projet, pour pouvoir l'exécuter à partir du module principal et de sous-modules.

<profile>
    <id>root-dir</id>
    <activation>
        <file>
            <exists>${project.basedir}/../../config/checkstyle.xml</exists>
        </file>
    </activation>
    <properties>
        <project.config.path>${project.basedir}/../config</project.config.path>
    </properties>
</profile>

il ne fonctionnera pas pour les modules imbriqués, mais je suis sûr qu'il peut être modifié pour cela en utilisant plusieurs profils avec différents exists 's. (Je ne sais pas pourquoi il devrait y en avoir "../.."dans l'étiquette de vérification et juste".."dans le remplacé à la propriété elle-même, mais il ne fonctionne que de cette façon.)

5
répondu Vic 2013-07-02 10:46:27

une autre alternative:

dans le pom parent, utiliser:

<properties>
   <rootDir>${session.executionRootDirectory}</rootDir>
<properties>

dans les poms enfants, vous pouvez faire référence à cette variable.

mise en garde principale: cela vous oblige à toujours exécuter la commande à partir du répertoire principal parent pom. Ensuite, si vous voulez exécuter des commandes (test par exemple) uniquement pour un module spécifique, utilisez cette syntaxe:

mvn test --projets

la configuration de la variable "path_to_test_data" peut alors être:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${surefire.plugin.version}</version>
    <configuration>
        <systemPropertyVariables>
            <path_to_test_data>${rootDir/../testdata}</path_to_test_data>
        </systemPropertyVariables>
    </configuration>
</plugin>
4
répondu Francois Marot 2015-10-20 15:58:57

j'ai trouvé une solution pour résoudre ce problème: utilisez $ {parent.relativePath}

<parent>
    <artifactId>xxx</artifactId>
    <groupId>xxx</groupId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>..</relativePath>
</parent>
<build>
    <filters>
        <filter>${parent.relativePath}/src/main/filters/filter-${env}.properties</filter>
    </filters>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>
3
répondu Caille 2012-07-13 15:57:29

vous êtes dans le projet C, le projet C est sous-module de B et B est sous-module de A. Vous essayez de joindre le répertoire src/test/config/etc du module D du projet C. D est également sous-module de A. l'expression suivante permet d'obtenir le chemin URI:

-Dparameter=file:/${basedir}/../../D/src/test/config/etc
3
répondu fatih tekin 2012-11-16 21:09:33
<plugins>
  <plugin>
    <groupId>org.codehaus.groovy.maven</groupId>
    <artifactId>gmaven-plugin</artifactId>
    <version>1.0</version>
    <executions>
      <execution>
        <phase>validate</phase>
        <goals>
          <goal>execute</goal>
        </goals>
        <configuration>
          <source>
            import java.io.File
            project.properties.parentdir = "${pom.basedir}"
            while (new File(new File(project.properties.parentdir).parent, 'pom.xml').exists()) {
                project.properties.parentdir = new File(project.properties.parentdir).parent
            }
          </source>
        </configuration>
      </execution>
    </executions>
  </plugin>
  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>properties-maven-plugin</artifactId>
    <version>1.0-alpha-2</version>
    <executions>
      <execution>
        <phase>initialize</phase>
        <goals>
          <goal>read-project-properties</goal>
        </goals>
        <configuration>
          <files>
            <file>${parentdir}/build.properties</file>
          </files>
        </configuration>
      </execution>
    </executions>
  </plugin>
  ...
2
répondu 2009-09-17 12:39:58

Dans un réponse à une autre question j'ai montré comment le maven-propriétés-plugin pourrait être étendu à l'utilisation de biens externes descripteurs définis dans les dépendances Maven.

vous pourriez étendre cette idée pour avoir plusieurs pots descripteurs, chacun avec le nom d'environnement dans le cadre de l'artifactId, contenant un ${env}.propriété. Ensuite, vous pouvez utiliser la propriété pour sélectionner le jar approprié et le fichier de propriétés, par exemple:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>properties-ext-maven-plugin</artifactId>
  <version>0.0.1</version>
  <executions>
    <execution>
      <id>read-properties</id>
      <phase>initialize</phase>
      <goals>
        <goal>read-project-properties</goal>
      </goals>
    </execution>
  </executions>                              
  <configuration>
    <filePaths>
      <!--assume the descriptor project has a file in the root of the jar -->
      <filePath>${env}.properties</filePath>
    </filePaths>
  </configuration> 
  <dependencies>
    <!-- reference the properties jar for the particular environment-->
    <dependency>
      <groupId>some.descriptor.group</groupId>
      <artifactId>env-${env}-descriptor</artifactId>
      <version>0.0.1</version>
    </dependency>
  </dependencies>
</plugin>
1
répondu Rich Seller 2017-05-23 11:54:41

je viens d'améliorer le script groovy d'en haut pour écrire la propriété dans le fichier de propriétés parent racine:

import java.io.*;
String p = project.properties['env-properties-file']
File f = new File(p)
if (f.exists()) {
try{
FileWriter fstream = new FileWriter(f.getAbsolutePath())
BufferedWriter out = new BufferedWriter(fstream)
String propToSet = f.getAbsolutePath().substring(0, f.getAbsolutePath().lastIndexOf(File.separator))
if (File.separator != "/") {
propToSet = propToSet.replace(File.separator,File.separator+File.separator+File.separator)
}
out.write("jacoco.agent = " + propToSet + "/lib/jacocoagent.jar")
out.close()
}catch (Exception e){
}
}
String ret = "../"
while (!f.exists()) {
f = new File(ret + p)
ret+= "../"
}
project.properties['env-properties-file-by-groovy'] = f.getAbsolutePath()
1
répondu Tcharl 2011-12-27 21:02:22

j'ai accédé au dir ci-dessus en utilisant ${basedir}..\src\

1
répondu Secelean Monica 2016-04-15 14:06:19

avez-vous essayé ../../env_${env}.properties ?

Normalement nous faisons ce qui suit lorsque module2 est au même niveau que les sous-modules

<modules>
    <module>../sub-module1</module>
    <module>../sub-module2</module>
    <module>../sub-module3</module>
</modules>

je pense que le ../.. serait vous faire sauter deux niveaux. Si non, vous pouvez contacter la fiche d'auteurs et de voir si c'est un problème connu.

0
répondu sal 2009-06-18 16:16:11

je pense que si vous utilisez le motif d'extension utilisé dans l'exemple pour FindBugs plugin & multimodule vous pouvez être en mesure de définir des propriétés globales liées à des chemins absolus. Il utilise un top

exemple pour module multiple

le top level pom dispose d'un projet de construction-configuration sans rapport et d'une application-parent pour les modules du projet multimodule. L'app-parent utilise l'extension pour se relier au projet build-config et obtenir des ressources. Ceci est utilisé pour transporter des fichiers de configuration communs vers les modules. Il peut être un conduit pour les propriétés ainsi. Vous pouvez écrire le dir supérieur à un fichier de propriété consommé par le build-config. (il semble trop complexe)

le problème est qu'un nouveau niveau supérieur doit être ajouté au projet multi-modules pour que cela fonctionne. J'ai essayé de mettre de côté step avec un projet de construction-configuration vraiment sans rapport mais il était kludgy et semblait fragile.

0
répondu Peter Kahn 2009-09-18 20:31:14

cela étend la réponse de romaintaz, ce qui est génial en ce que résout le problème et indique clairement la fonctionnalité manquante de maven. J'ai trouvé une version plus récente du plugin, et j'ai ajouté le cas où le projet pourrait être plus de 3 niveaux de profondeur.

<pluginManagement>
  <plugins>
    ..
    <plugin>
      <groupId>org.codehaus.gmaven</groupId>
      <artifactId>groovy-maven-plugin</artifactId>
      <version>2.0</version>
    </plugin>
    ..
  </plugins>
</pluginManagement>

j'ai choisi de ne pas utiliser une propriété pour définir le nom du fichier. Notez si la construction.propriétés n'est pas trouvé cela tournera pour toujours. J'ai ajouté un .git dir détection, mais ne voulait pas compliquer la réponse donc ce n'est pas indiqué ici.

  <plugin>
      <groupId>org.codehaus.gmaven</groupId>
      <artifactId>groovy-maven-plugin</artifactId>
      <executions>
          <execution>
              <phase>validate</phase>
              <goals>
                  <goal>execute</goal>
              </goals>
              <configuration>
                 <source>
                    import java.io.File;
                    String p = "build.properties";
                    while(true) {
                      File f = new File(p); 
                      if(f.exists()) {
                        project.properties['project-properties-file'] = f.getAbsolutePath();
                        break;
                      }
                      else {
                        p = "../${p}";
                      }
                    }
                </source>
              </configuration>
          </execution>
      </executions>
  </plugin>
0
répondu Bruce Edge 2015-09-08 19:21:52

j'avais besoin de résoudre un problème similaire pour le dépôt local placé dans le projet principal du projet multi-modules. Essentiellement le vrai chemin était ${basedir} / lib. Finalement j'ai réglé cela dans mon parent.pom :

<repository>
    <id>local-maven-repo</id>
    <url>file:///${basedir}/${project.parent.relativePath}/lib</url>
</repository>

que basedir montre toujours au module local actuel, il n'y a aucun moyen d'obtenir le chemin au projet" maître " (la honte de Maven). Certains de mes sous-modules sont un dir plus profond, certains sont deux DIR plus profond, mais Tous sont direct submodules du parent qui définit L'URL repo.

Si cela ne résout pas le problème en général. Vous pouvez toujours le combiner avec la réponse acceptée de Clay et de définir d'autres propriétés - fonctionne très bien et doit être redéfini seulement pour les cas où la valeur de parent.pom n'est pas assez bon. Ou vous pouvez simplement reconfigurer le plugin - ce que vous ne faites que dans les artéfacts POM (parents d'autres sous-modules). La valeur extraite dans la propriété est probablement meilleure si vous en avez besoin sur plus d'endroits, surtout quand rien dans la configuration du plugin ne change.

en utilisant basedir dans la valeur était la partie essentielle ici, parce que L'URL file://${project.parent.relativePath}/lib ne voulait pas faire le tour (j'ai enlevé une barre oblique pour la rendre relative). En utilisant la propriété qui me donne bon chemin absolu et puis aller relative de lui était nécessaire.

quand le chemin n'est pas URL/URI, ce n'est probablement pas un tel problème de laisser tomber basedir .

0
répondu virgo47 2015-10-13 16:28:25

La première réponse devrait fonctionner. Dans la ligne d'héritage parent-enfant, la propriété définie par l'utilisateur avec une propriété maven-default au niveau supérieur POM (dans ce cas <parent.base.directory>${project.parent.basedir}</parent.base.directory> ) sera définie comme elle traverse l'arbre. En d'autres termes, ${parent.base.directory} sera fixé correctement dans différents POM enfant.

Remarque Vous ne devez pas utiliser ${parent.basedir} comme votre propriété définie par l'utilisateur parce qu'elle est la même que la propriété ${project.parent.basedir} par défaut de maven. Sinon, il erreur d'expression récursive dans maven. C'est pourquoi j'utilise ${parent.base.directory} dans la réponse.

l'Espoir c'est la racine de la solution au problème.

-1
répondu Van 2016-07-24 16:18:29