52 votes

Comment partager des propriétés communes entre plusieurs projets Maven?

J'ai plusieurs projets construits par maven, et je tiens à partager certaines propriétés communes entre eux - printemps version du driver mysql version svn de l'url de base, etc. - donc, je peux mettre à jour une fois et il pourra être répercuté sur tous les projets.

J'ai pensé que d'avoir un seul super pom avec toutes les propriétés, mais si je change de le problème j'ai besoin de soit incrémenter sa version (et mettre à jour tous les poms héritent de celui-ci) ou de le supprimer à partir de tous les développeurs de machines à laquelle je ne veux pas faire.

Pouvez spécifier ces paramètres à l'extérieur, pom? Je veux toujours avoir l'emplacement externe définition dans un pom parent.

27voto

romaintaz Points 32120

Ce que vous pouvez faire est d'utiliser les Propriétés du plugin Maven. Cela vous permettra de définir vos propriétés dans un fichier externe, et le plugin va lire ce fichier.

Avec cette configuration :

<build>
    <plugins>
        <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>my-file.properties</file>
                        </files>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

et si vous avez, dans votre fichier de propriétés, les lignes suivantes:

spring-version=1.0
mysql-version=4.0.0

puis c'est la même chose que si vous avez écrit, dans votre pom.xml, les lignes suivantes:

<properties>
    <spring-version>1.0</spring-version>
    <mysql-version>4.0.0</mysql-version>
</properties>

L'utilisation de ce plugin, vous aurez plusieurs avantages:

  • Définir facilement une longue liste de propriétés
  • Modifier les valeurs de ces propriétés sans modifier le parent pom.xml.

14voto

Mike Cornell Points 2661

Notez que l'idée originale que j'ai ici est quelque chose que je fais, mais que j'ai peut-être trouvé une bien meilleure idée que j'ai également listé ci-dessous. Je voulais garder les deux idées ici par souci d'exhaustivité dans le cas où la nouvelle idée de ne pas travailler.


Je pense que vous pouvez résoudre ce problème en utilisant le pom parent, mais vous devez disposer d'un référentiel et un IC outil de construction.

J'ai plusieurs projets qui héritent tous de la base de propriétés à partir d'un POM parent. Nous utilisons Java 1.5, de sorte que la propriété est configuration. Tout est en UTF-8. Tous les rapports que je souhaite exécuter, Sonar de configuration, etc, est à l'intérieur du POM parent.

En supposant que votre projet est dans le contrôle de version et vous avez un outil CI, lors de votre arrivée, votre outil CI peuvent construire POM du projet et de déployer l'INSTANTANÉ à l'maven repos. Si votre projet le point à l'INSTANTANÉ de la version de la mère POM, ils vont vérifier le référentiel, afin de valider qu'ils disposent de la dernière version...si ce n'est de télécharger la dernière version. Donc, si vous mettez à jour le parent, tous les autres projets de mise à jour.

L'astuce, je suppose, libérant un INSTANTANÉ. Je dirais que vos communiqués allez trouver beaucoup moins fréquemment que vos modifications. Si vous exécutez une version de votre POM, puis mettre à jour votre POMs qui héritent d'eux et de les vérifier dans le contrôle de version. Laissez les devs savent qu'ils ont besoin de faire une mise à jour et à partir de là.

Vous pourriez simplement déclencher construit il y forçant la nouvelle Pdm dans le référentiel et demandez ensuite à tous les devs chercher les modifications automatiquement lors de la construction.


J'ai supprimé la DERNIÈRE VERSION mots-clés idée, car ils ne fonctionnent pas pour les parents de Chrysanthèmes. Ils ne fonctionnent que pour les dépendances ou des plugins. Le problème est dans DefaultMavenProjectBuilder. Essentiellement, il a de la difficulté à déterminer qui référentiel de regarder pour les parents afin de déterminer quelle est la dernière ou la version. Je ne sais pas pourquoi c'est différent pour les dépendances ou les plugins si.


Cela ressemble à ces serait moins pénible que d'avoir à mettre à jour les Pdm à chaque changement pour le POM parent.

7voto

Rich Seller Points 46052

Je pense que les propriétés-maven-plugin est la bonne approche à long terme, mais que vous avez répondu à cette réponse, il ne permet pas les propriétés pour être héritée. Il y a quelques facilités dans maven-partagé-io qui vous permettent de découvrir les ressources du projet de chemin de classe. J'ai inclus un peu de code ci-dessous qui étend les propriétés du plugin pour trouver les propriétés des fichiers dans les dépendances du plugin.

La configuration déclare un chemin d'accès à un fichier de propriétés, parce que le descripteur de projet est déclarée dans la configuration du plugin, il est accessible à la ClasspathResourceLocatorStrategy. La configuration peut être définie dans un projet parent, et sera héritée par tous les projets enfants (si vous faites cela, éviter de déclarer tous les fichiers qu'ils ne sont pas être découvert, seulement la filePaths de la propriété).

La configuration ci-dessous suppose qu'il existe un autre pot projet appelé nom.vendeur.riche:test-propriétés-descripteur:0.0.1 qui a un fichier appelé externes.propriétés emballés dans le pot (c'est à dire qu'il a été défini dans src/main/resources).

<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>
      <filePath>external.properties</filePath>
    </filePaths>
  </configuration> 
  <dependencies>
    <!-- declare any jars that host the required properties files here -->
    <dependency>
      <groupId>name.seller.rich</groupId>
      <artifactId>test-properties-descriptor</artifactId>
      <version>0.0.1</version>
    </dependency>
  </dependencies>
</plugin>

Le pom pour le plugin projet ressemble à cela:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>properties-ext-maven-plugin</artifactId>
  <packaging>maven-plugin</packaging>
  <version>0.0.1</version>
  <dependencies>
    <dependency>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>properties-maven-plugin</artifactId>
      <version>1.0-alpha-1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven.shared</groupId>
      <artifactId>maven-shared-io</artifactId>
      <version>1.1</version>
    </dependency>
  </dependencies>
</project>

Le mojo est une copie de l'propriétés du plugin ReadPropertiesMojo, avec un supplément de "filePaths" de la propriété pour vous permettre de définir le chemin d'accès relatif à l'externe fichier de propriétés dans le classpath, il rend les fichiers de la propriété en option, et ajoute la readPropertyFiles() et getLocation() les méthodes pour rechercher les fichiers et fusionner toutes filePaths dans les fichiers de tableau avant de continuer. J'ai commenté mes modifications pour les rendre plus claires.

package org.codehaus.mojo.xml;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file 
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 * KIND, either express or implied.  See the License for the 
 * specific language governing permissions and limitations 
 * under the License.
 */

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.io.location.ClasspathResourceLocatorStrategy;
import org.apache.maven.shared.io.location.FileLocatorStrategy;
import org.apache.maven.shared.io.location.Location;
import org.apache.maven.shared.io.location.Locator;
import org.apache.maven.shared.io.location.LocatorStrategy;
import org.apache.maven.shared.io.location.URLLocatorStrategy;
import org.codehaus.plexus.util.cli.CommandLineUtils;

/**
 * The read-project-properties goal reads property files and stores the
 * properties as project properties. It serves as an alternate to specifying
 * properties in pom.xml.
 * 
 * @author <a href="mailto:zarars@gmail.com">Zarar Siddiqi</a>
 * @author <a href="mailto:Krystian.Nowak@gmail.com">Krystian Nowak</a>
 * @version $Id: ReadPropertiesMojo.java 8861 2009-01-21 15:35:38Z pgier $
 * @goal read-project-properties
 */
public class ReadPropertiesMojo extends AbstractMojo {
    /**
     * @parameter default-value="${project}"
     * @required
     * @readonly
     */
    private MavenProject project;

    /**
     * The properties files that will be used when reading properties.
     * RS: made optional to avoid issue for inherited plugins
     * @parameter
     */
    private File[] files;

    //Begin: RS addition
    /**
     * Optional paths to properties files to be used.
     * 
     * @parameter
     */
    private String[] filePaths;
    //End: RS addition

    /**
     * If the plugin should be quiet if any of the files was not found
     * 
     * @parameter default-value="false"
     */
    private boolean quiet;

    public void execute() throws MojoExecutionException {
        //Begin: RS addition
        readPropertyFiles();
        //End: RS addition

        Properties projectProperties = new Properties();
        for (int i = 0; i < files.length; i++) {
            File file = files[i];

            if (file.exists()) {
                try {
                    getLog().debug("Loading property file: " + file);

                    FileInputStream stream = new FileInputStream(file);
                    projectProperties = project.getProperties();

                    try {
                        projectProperties.load(stream);
                    } finally {
                        if (stream != null) {
                            stream.close();
                        }
                    }
                } catch (IOException e) {
                    throw new MojoExecutionException(
                            "Error reading properties file "
                                    + file.getAbsolutePath(), e);
                }
            } else {
                if (quiet) {
                    getLog().warn(
                            "Ignoring missing properties file: "
                                    + file.getAbsolutePath());
                } else {
                    throw new MojoExecutionException(
                            "Properties file not found: "
                                    + file.getAbsolutePath());
                }
            }
        }

        boolean useEnvVariables = false;
        for (Enumeration n = projectProperties.propertyNames(); n
                .hasMoreElements();) {
            String k = (String) n.nextElement();
            String p = (String) projectProperties.get(k);
            if (p.indexOf("${env.") != -1) {
                useEnvVariables = true;
                break;
            }
        }
        Properties environment = null;
        if (useEnvVariables) {
            try {
                environment = CommandLineUtils.getSystemEnvVars();
            } catch (IOException e) {
                throw new MojoExecutionException(
                        "Error getting system envorinment variables: ", e);
            }
        }
        for (Enumeration n = projectProperties.propertyNames(); n
                .hasMoreElements();) {
            String k = (String) n.nextElement();
            projectProperties.setProperty(k, getPropertyValue(k,
                    projectProperties, environment));
        }
    }

    //Begin: RS addition
    /**
     * Obtain the file from the local project or the classpath
     * 
     * @throws MojoExecutionException
     */
    private void readPropertyFiles() throws MojoExecutionException {
        if (filePaths != null && filePaths.length > 0) {
            File[] allFiles;

            int offset = 0;
            if (files != null && files.length != 0) {
                allFiles = new File[files.length + filePaths.length];
                System.arraycopy(files, 0, allFiles, 0, files.length);
                offset = files.length;
            } else {
                allFiles = new File[filePaths.length];
            }

            for (int i = 0; i < filePaths.length; i++) {
                Location location = getLocation(filePaths[i], project);

                try {
                    allFiles[offset + i] = location.getFile();
                } catch (IOException e) {
                    throw new MojoExecutionException(
                            "unable to open properties file", e);
                }
            }

            // replace the original array with the merged results
            files = allFiles;
        } else if (files == null || files.length == 0) {
            throw new MojoExecutionException(
                    "no files or filePaths defined, one or both must be specified");
        }
    }
    //End: RS addition

    /**
     * Retrieves a property value, replacing values like ${token} using the
     * Properties to look them up. Shamelessly adapted from:
     * http://maven.apache.
     * org/plugins/maven-war-plugin/xref/org/apache/maven/plugin
     * /war/PropertyUtils.html
     * 
     * It will leave unresolved properties alone, trying for System properties,
     * and environment variables and implements reparsing (in the case that the
     * value of a property contains a key), and will not loop endlessly on a
     * pair like test = ${test}
     * 
     * @param k
     *            property key
     * @param p
     *            project properties
     * @param environment
     *            environment variables
     * @return resolved property value
     */
    private String getPropertyValue(String k, Properties p,
            Properties environment) {
        String v = p.getProperty(k);
        String ret = "";
        int idx, idx2;

        while ((idx = v.indexOf("${")) >= 0) {
            // append prefix to result
            ret += v.substring(0, idx);

            // strip prefix from original
            v = v.substring(idx + 2);

            idx2 = v.indexOf("}");

            // if no matching } then bail
            if (idx2 < 0) {
                break;
            }

            // strip out the key and resolve it
            // resolve the key/value for the ${statement}
            String nk = v.substring(0, idx2);
            v = v.substring(idx2 + 1);
            String nv = p.getProperty(nk);

            // try global environment
            if (nv == null) {
                nv = System.getProperty(nk);
            }

            // try environment variable
            if (nv == null && nk.startsWith("env.") && environment != null) {
                nv = environment.getProperty(nk.substring(4));
            }

            // if the key cannot be resolved,
            // leave it alone ( and don't parse again )
            // else prefix the original string with the
            // resolved property ( so it can be parsed further )
            // taking recursion into account.
            if (nv == null || nv.equals(nk)) {
                ret += "${" + nk + "}";
            } else {
                v = nv + v;
            }
        }
        return ret + v;
    }

    //Begin: RS addition
    /**
     * Use various strategies to discover the file.
     */
    public Location getLocation(String path, MavenProject project) {
        LocatorStrategy classpathStrategy = new ClasspathResourceLocatorStrategy();

        List strategies = new ArrayList();
        strategies.add(classpathStrategy);
        strategies.add(new FileLocatorStrategy());
        strategies.add(new URLLocatorStrategy());

        List refStrategies = new ArrayList();
        refStrategies.add(classpathStrategy);

        Locator locator = new Locator();

        locator.setStrategies(strategies);

        Location location = locator.resolve(path);
        return location;
    }
    //End: RS addition
}

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