web-dev-qa-db-fra.com

Lecture du fichier de propriétés à partir du fichier POM dans Maven

Pourquoi cela ne fonctionne-t-il pas? Comment choisir les numéros de version dans le fichier de propriétés.

Lecture des propriétés dans pom.xml

<project>
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>properties-maven-plugin</artifactId>
        <version>1.0</version>
        <executions>
          <execution>
            <phase>initialize</phase>
            <goals>
              <goal>read-project-properties</goal>
            </goals>
          </execution>
          <configuration>
            <files>
              <file>dev.properties</file>
            </files>
          </configuration>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Dans dev.properties

org.aspectj.aspectjrt.version = 1.6.11

Dépendance dans pom.xml

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${org.aspectj.aspectjrt.version}</version>
        </dependency>

Erreur: la dépendance doit être une version valide

21
Debajyoti Das

Lorsque vous démarrez Maven à partir de la ligne de commande, il passe par plusieurs étapes. Voici une pseudo description de ces étapes, je simplifie intentionnellement le séquencement exact (avec le risque de dire des choses qui sont légèrement incorrectes/désordonnées) afin que vous puissiez voir pourquoi ce que vous essayez de faire ne peut pas fonctionner.

  1. Tout d'abord, il analyse votre ligne de commande, toutes les propriétés définies sur la ligne de commande en utilisant le -Dname=value Sont injectées dans le MavenSession

  2. Les options de ligne de commande définissant le réacteur sont vérifiées pour décider quelle devrait être la liste des projets à construire (également appelé réacteur). -N Signifie construire uniquement la racine pom.xml, -pl Permet de spécifier une liste de modules à construire, -am Et -AMD Permet d'ajouter en amont ou en aval, respectivement, des modules de ceux spécifiés par -pl. Maven n'a analysé aucun fichier pom.xml Pour le moment.

  3. Les règles d'activation de profil -P Sont analysées pour voir quels profils activer.

  4. Maintenant, Maven a suffisamment de connaissances pour commencer à analyser les fichiers pom.xml. Il commence par charger et analyser la racine pom.xml, C'est-à-dire celle dans le répertoire courant (ou si vous avez spécifié une alternative pom.xml Avec -f Alors celle-là). Cette analyse initiale se concentre uniquement sur la détermination de la liste des projets à construire. L'activation de profil n'est prise en compte que dans la mesure où elle peut affecter la liste des <modules> Disponibles. Les coordonnées Group Id, Artifact Id, Version et Packaging dans pom.xml Ne peuvent pas contenir de propriétés car l'analyse des propriétés dans pom.xml N'a pas eu lieu à ce stade. (Le lecteur attentif verra également que cela explique également pourquoi vous ne pouvez pas activer les profils basés sur les propriétés dans le pom.xml, Car seules les propriétés du système ont été analysées à ce stade)

  5. Une fois que l'ensemble des projets a été validé, Maven fait maintenant un peu plus d'analyse de ces fichiers pom.xml Pour construire la liste des extensions de construction (le cas échéant) et la liste des plugins. À ce stade, l'analyse syntaxique nécessite une évaluation du <properties> Dans chaque projet, c'est à ce moment-là que ceux-ci sont évalués et "injectés" dans le modèle efficace. Ainsi, vous pouvez utiliser les propriétés système et les propriétés pom pour définir les coordonnées et les dépendances supplémentaires dans (xpath) /project/build/extensions, /project/build/pluginManagement/plugins/plugin, /project/build/pluginManagement/plugins/plugin/dependencies, /project/build/plugins/plugin Et /project/build/plugins/plugin/dependencies.

  6. Maven commence maintenant à analyser la liste des objectifs et des phases spécifiés sur la ligne de commande. Les objectifs partiellement spécifiés sont évalués pour une correspondance avec la liste des plugins. La correspondance doit être unique pour tous les projets contre lesquels l'objectif du plug-in sera exécuté (c'est-à-dire s'il s'agit d'un objectif d'agrégateur, la correspondance n'est requise qu'à la racine, mais pour tous les autres objectifs "normaux", le nom abrégé du plug-in doit être le même plugin pour tous les projets). Les phases du cycle de vie doivent provenir de l'un des cycles de vie par défaut ou d'un cycle de vie défini dans une extension de build.

  7. À partir de la liste analysée des objectifs et des phases, Maven construit le plan de construction, c'est-à-dire ce qu'il va faire sur quels projets et dans quel ordre. Pour ce faire, Maven doit analyser la liste des dépendances de projet définies dans les fichiers de projets du réacteur pom.xml. En effet, une dépendance peut être produite par un autre projet au sein du réacteur, forçant ainsi un séquencement de l'exécution du projet. Ainsi, vous pouvez utiliser les propriétés système et les propriétés de pom pour définir les coordonnées et les dépendances supplémentaires dans (xpath) /project/dependencyManagement/dependencies/dependency Et /project/dependencies/dependency Mais notez qu'à ce stade, aucun plugin n'a été exécuté.

  8. Maintenant que Maven a le plan de build, il commence à suivre ce plan dans l'ordre qu'il a construit. Si le premier objectif/phase sur la CLI était un objectif, alors cet objectif sera invoqué. Si le premier objectif/phase était une phase du cycle de vie de construction par défaut, alors Maven commencera par la phase initialize et exécutera tous les plugins liés à cette phase ... en continuant de manière similaire le long de la liste des phases puis la liste des projets. Notez également que la phase initialize n'est exécutée que dans le cadre du cycle de vie de génération par défaut. Il n'est pas exécuté sur les cycles de vie de site propres ou par défaut, et il n'est exécuté sur aucun cycle de vie personnalisé. (Le lecteur attentif conclura que cela met en évidence un autre problème avec la technique que la question tente). Remarque: gardez à l'esprit que les objectifs d'agrégateur forment une "rupture" dans le réacteur, donc si vous demandez à Maven d'exécuter clean package foo:bar sitefoo:bar Est un objectif mojo d'agrégateur, alors clean package sera exécuté sur tous les projets du réacteur, puis foo:bar sera exécuté sur la racine, puis site sera exécuté sur tous les projets du réacteur. En d'autres termes, le plan de construction prendra la plus longue série continue d'objectifs et de phases non agrégateurs, divisée par les plus longues séries continues d'objectifs d'agrégateur.

  9. Avant d'appeler chaque mojo (c.-à-d. Objectif lié à une phase ou directement spécifié à partir de la ligne de commande) Maven évalue le pom.xml Pour le <configuration> Effectif de ce mojo. À ce stade, Maven dispose des propriétés système, les propriétés spécifiées dans le pom et toutes les propriétés injectées dans le MavenSession par des mojos exécutés précédemment. Ainsi, <configuration> Peut référencer n'importe laquelle de ces propriétés ...

    À part

    Maintenant, il y a une mise en garde ... si vous dites définir (xpath) /project/build/directory Sur ${some-property-i-will-set-via-a-mojo} Et ensuite référencer cela à partir de votre <configuration>, Et bien la triste nouvelle est que (xpath) /project/build/directory Aura été évalué dans l'efficacité pom.xml avant toute exécution de plugin, donc ${project.build.directory} Aura reçu la valeur littérale ${some-property-i-will-set-via-a-mojo} et qui est de type Java.io.File Dans le MavenProject donc ce que vous aurez réellement eu c'est new File(project.getBaseDir(),"${some-property-i-will-set-via-a-mojo}"). Si le champ <configuration> Dans lequel vous effectuez l'injection est de type File, aucune conversion de type n'est requise et la valeur sera donc injectée directement et aucune substitution de propriété n'aura eu lieu.

    Il existe d'autres cas Edge, comme celui décrit ci-dessus, mais en général la substitution de propriété fonctionnera avec les propriétés "mojo injected" (telles que celles fournies par Mojo's Properties Maven Plugin =) dans les sections <configuration>. Cela ne fonctionnera pas en dehors de ces sections.

Voici donc la règle empirique rapide de Stephen pour les différents types de propriétés:

Propriétés système

Ceux-ci fonctionnent partout ... mais sont extrêmement dangereux dans /project/(parent/)?/(groupId|artifactId|version|packaging) car vous n'avez aucun contrôle sur les propriétés système qui seront définies lorsque le projet sera tiré en tant que dépendance transitive. L'utilisation de l'extension ${...} Dans /project/(parent/)?/(groupId|artifactId|version|packaging) doit être considérée comme équivalente à la conduite d'une voiture à 200 km/h avec une pointe métallique de 30 cm (12 pouces) dépassant du volant à la place d'un airbag ... oh et pas de ceinture de sécurité ... et vous venez d'avoir 10 unités d'alcool et deux lignes de cocaïne.

Propriétés pom.xml (et propriétés settings.xml)

Ceux-ci fonctionnent dans la plupart des endroits, mais ne sont jamais disponibles dans /project/(parent/)?/(groupId|artifactId|version|packaging) (car ils n'ont pas été analysés lors de l'évaluation de ces champs) et ne sont pas disponibles pour la prise en compte des profils actifs (encore une fois car ils n'ont pas été analysés lorsque l'activation du profil est en cours d'évaluation)

Propriétés injectées de Mojo

Celles-ci fonctionnent dans les sections <configuration> Et peuvent (en raison de l'interpolation récursive des paramètres Mojo String injectés) fonctionner lorsqu'elles sont utilisées indirectement, mais étant donné l'incertitude impliquée, la recommandation est de limiter leur utilisation à la <configuration> Section des plugins et rapports uniquement.

Une dernière chose

Pensez à ce qui se passe lorsque votre projet est répertorié comme une dépendance. Si vous aviez spécifié ses dépendances en utilisant un mojo pour les extraire d'un fichier .properties Sur le disque, Maven n'a aucun moyen de le répliquer lorsque votre dépendance a été extraite du référentiel Maven. Maven serait donc incapable de déterminer les dépendances. Ainsi, cela ne pourrait jamais fonctionner.

Ce que vous pourriez faire, c'est utiliser un système externe (par exemple ANT) pour générer le pom.xml À partir d'un modèle avec les versions remplacées dans ce fichier. Et puis utilisez le modèle instancié pour construire.

89
Stephen Connolly