Configuration 如何在几个maven项目之间共享公共属性?
我有几个由maven构建的项目,我想在它们之间共享一些共同的属性——spring版本、mysql驱动程序版本、svn基本url等等——所以我可以对它们进行一次更新,它将反映在所有项目上 我曾想过拥有一个具有所有属性的超级pom,但如果我改变了其中一个问题,我需要增加它的版本(并更新它继承的所有pom),或者从所有开发人员的机器上删除它,我不想这样做Configuration 如何在几个maven项目之间共享公共属性?,configuration,maven-2,properties-file,Configuration,Maven 2,Properties File,我有几个由maven构建的项目,我想在它们之间共享一些共同的属性——spring版本、mysql驱动程序版本、svn基本url等等——所以我可以对它们进行一次更新,它将反映在所有项目上 我曾想过拥有一个具有所有属性的超级pom,但如果我改变了其中一个问题,我需要增加它的版本(并更新它继承的所有pom),或者从所有开发人员的机器上删除它,我不想这样做 可以在pom外部指定这些参数吗?我仍然希望在父pom中具有外部位置定义。您可以使用。这将允许您在外部文件中定义属性,插件将读取此文件 使用此配置:
可以在pom外部指定这些参数吗?我仍然希望在父pom中具有外部位置定义。您可以使用。这将允许您在外部文件中定义属性,插件将读取此文件 使用此配置:
<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>
这与您在pom.xml中编写以下行是一样的:
spring-version=1.0
mysql-version=4.0.0
<properties>
<spring-version>1.0</spring-version>
<mysql-version>4.0.0</mysql-version>
</properties>
1
4.0.0
使用此插件,您将获得以下好处:
- 轻松设置一长串属性
- 修改这些属性的值,而不修改父pom.xml
- 请注意,我这里的原始想法是我正在做的事情,但我可能已经找到了一个更好的想法,我也在下面列出了。为了完整起见,我想把这两个想法都保留在这里,以防新想法不起作用
我认为您可以使用父pom解决这个问题,但是您需要有一个maven存储库和一个CI构建工具 我有几个项目都从父POM继承基本属性。我们使用Java1.5,所以在那里设置了build属性。一切都是UTF-8。我希望运行的所有报告、声纳设置等都在父POM中 假设您的项目处于版本控制中,并且您有一个CI工具,当您签入时,您的CI工具可以构建到POM项目,并将快照部署到maven repos。如果您的项目指向父POM的快照版本,它们将检查存储库以验证是否具有最新版本…如果没有,则下载最新版本。因此,如果更新父项目,所有其他项目都将更新 我想关键在于发布快照。我要说的是,你的发布会比你的更改来得少得多。因此,您执行POM的发布,然后更新从POM继承的POM,并将其签入版本控制。让开发人员知道他们需要进行更新并从那里开始 您可以在那里触发构建,强制将新POM放入存储库,然后让所有开发人员在构建时自动获取更改
我删除了最新发布的关键字,因为它们不适用于父级POM。它们只适用于依赖项或插件。问题区域位于DefaultMavenProjectBuilder中。本质上,它很难确定要查找哪个存储库来确定最新版本或发布版本。不过,我不知道为什么这与依赖项或插件不同
听起来这比每次更改父POM时都要更新POM要轻松得多。从长远来看,我认为properties maven插件是正确的方法,但当您回答这个问题时,它不允许继承属性。maven共享io中有一些工具允许您发现项目类路径上的资源。我在下面包含了一些扩展属性插件的代码,以在插件的依赖项中查找属性文件 配置声明了属性文件的路径,因为描述符项目是在插件配置上声明的,所以ClassPathResourceLocator策略可以访问它。配置可以在父项目中定义,并将由所有子项目继承(如果这样做,请避免声明任何文件,因为它们不会被发现,请仅设置filePaths属性) 下面的配置假定存在另一个名为name.seller.rich:testproperties descriptor:0.0.1的jar项目,该项目将一个名为external.properties的文件打包到jar中(即,它是在src/main/resources中定义的)
org.codehaus.mojo
*@作者
*@version$Id:ReadPropertiesMojo.java 8861 2009-01-21 15:35:38Z pgier$
*@goal读取项目属性
*/
公共类ReadPropertiesMojo扩展了AbstractMojo{
/**
*@parameter default value=“${project}”
*@必需
*@readonly
*/
私人马文项目;
/**
*读取属性时将使用的属性文件。
*RS:为避免继承插件的问题,将其设置为可选
*@参数
*/
私有文件[]文件;
//开始:RS添加
/**
*要使用的属性文件的可选路径。
*
*@参数
*/
私有字符串[]文件路径;
//完:RS加法
/**
*如果没有找到任何文件,插件是否应该保持安静
*
*@parameter default value=“false”
*/
私人布尔安静;
public void execute()引发MojoExecutionException异常{
//开始:RS添加
readPropertyFiles();
//完:RS加法
Properties projectProperties=新属性();
对于(int i=0;i<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>
<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>
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
}