Frage

Ich habe mehrere Projekte, die von Maven gebaut, und ich will unter ihnen einige gemeinsame Eigenschaften teilen - Feder Version, MySQL-Treiberversion, svn Basis-URL, usw. - so kann ich sie einmal aktualisieren, und es wird auf allen Projekten widerspiegeln .

Ich dachte an einen einzigen Super-pom mit allen Eigenschaften, aber wenn ich eines des Problems, das ich entweder müssen ändere ihre Version erhöhen (und zu aktualisieren all Poms von ihm erben) oder es von allen Entwicklern zu löschen "Maschinen, die ich will nicht zu tun.

Kann diese Parameter extern an den pom angeben? Ich mag immer noch die externe Ortsdefinition in einem übergeordneten pom haben.

War es hilfreich?

Lösung

Beachten Sie, dass die ursprüngliche Idee, die ich hier habe, ist etwas, was ich tue, aber dass ich eine viel bessere Idee hat gefunden, die ich auch aus unten aufgeführt habe. Ich wollte hier beiden Ideen im Fall der Vollständigkeit halber halten die neuere Idee hat nicht Arbeit.


Ich glaube, Sie dieses Problem lösen können die Eltern pom verwenden, aber man braucht ein Maven-Repository und ein CI-Build-Tool haben.

habe ich mehrere Projekte habe, die alle Basiseigenschaften von einem übergeordneten POM erben. Wir verwenden Java 1.5, so dass Build-Eigenschaft ist es Setup. Alles ist UTF-8. Alle Berichte, die ich Sonar Setup ausführen möchten, usw., ist innerhalb des übergeordneten POM.

Wenn Ihr Projekt wird in der Versionskontrolle und Sie haben ein CI-Tool erhalten, wenn Sie beim Check-in Ihrem CI-Tool POM Projekt aufbauen kann und die SNAPSHOT auf die Maven repos einzusetzen. Wenn Sie Ihre Projekte auf die SNAPSHOT Version des POM Eltern zeigen, werden sie das Repository überprüfen, um zu bestätigen, dass sie die neueste Version haben ... wenn sie nicht die neueste Version herunterzuladen. Also, wenn Sie das übergeordnete aktualisieren, werden alle anderen Projekte aktualisieren.

Der Trick, nehme ich an mit einem SNAPSHOT ist die Freigabe. Ich würde sagen, Ihre Veröffentlichungen viel seltener als die Änderungen kommen werden. So haben Sie eine Veröffentlichung Ihrer POM ausführen, dann POMs aktualisieren, die von ihnen erben und überprüfen Sie sie in die Versionskontrolle. Lassen Sie die Devs wissen, dass sie ein Update und gehen von dort tun müssen.

Sie könnten nur Trigger dort baut die neuen POMs in das Repository zu zwingen und dann haben alle die Devs die Änderungen automatisch auf Build holen.


Ich habe die AKTUELLE / RELEASE Keywords Idee entfernt, weil sie für Eltern POMs nicht funktionieren. Sie arbeiten nur für Abhängigkeiten oder Plugins. Der Problembereich ist in DefaultMavenProjectBuilder. Im Wesentlichen hat es Schwierigkeiten bestimmen, welche Repository für die Eltern zu suchen, um festzustellen, was die neueste oder Release-Version ist. Nicht sicher, warum dies allerdings für Abhängigkeiten oder Plugins unterschiedlich ist.


Es klingt wie diese weniger schmerzhaft sein würde, als mit dem POMs bei jeder Änderung an die Mutter POM zu aktualisieren.

Andere Tipps

Was Sie tun können, ist die Eigenschaften Maven Plugin . So können Sie Ihre Eigenschaften in einer externen Datei definieren, und das Plugin wird diese Datei lesen.

Mit dieser Konfiguration:

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

und wenn Sie in Ihren Eigenschaften Datei die folgenden Zeilen:

spring-version=1.0
mysql-version=4.0.0

, dann ist es das gleiche wie wenn Sie geschrieben haben, in Ihrem pom.xml, die folgenden Zeilen:

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

Dieses Plugin, werden mehrere Vorteile:

  • Stellen Sie einfach eine lange Liste von Eigenschaften
  • Ändern Sie die Werte dieser Eigenschaften, ohne die Eltern pom.xml zu ändern.

Ich denke, die Eigenschaften-Maven-Plugin der richtige Ansatz ist langfristig, aber wie Sie zu dieser Antwort reagiert es nicht zulassen, die Eigenschaften vererbt werden. Es gibt einige Einrichtungen in maven-shared-io, mit denen Sie Ressourcen auf dem Projekt Classpath zu entdecken. Ich habe einige Code unten enthalten, dass die Eigenschaften Plugin erweitert Properties-Dateien in den Abhängigkeiten des Plugins zu finden.

Die Konfiguration einen Pfad erklärt, eine Eigenschaftendatei, da das Descriptor-Projekt auf der Plugin-Konfiguration deklariert wird, ist es für den ClasspathResourceLocatorStrategy zugänglich. Die Konfiguration kann in einem übergeordneten Projekt definiert werden, und wird von allen untergeordneten Projekte vererbt werden (wenn Sie dies zu vermeiden tun erklärt alle Dateien, da sie nicht entdeckt werden, wird nur die Dateipfade Eigenschaft).

Die folgende Konfiguration geht davon aus, dass es ein anderes Gefäß Projekt ist name.seller.rich:test-properties-descriptor:0.0.1 genannt, die eine Datei mit dem Namen external.properties in das Glas verpackt hat (dh es wurde in src definiert / main / Ressourcen).

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

Das pom für das Plugin-Projekt sieht wie folgt aus:

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

Die mojo eine Kopie der Eigenschaften ist ReadPropertiesMojo Plugin, mit einem zusätzlichen „Dateipfade“ Eigenschaft, damit Sie den relativen Pfad zu den externen Eigenschaften in der Classpath-Datei definieren, macht es die Dateien Eigenschaft optional, und fügt die readPropertyFiles ( ) und getLocation () Methoden, um die Dateien zu lokalisieren und alle Dateipfade in die Dateien Array zusammenführen, bevor fortsetzt. Ich habe meine Änderungen kommentiert sie klarer zu machen.

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
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top