如何从Maven POM中的文件设置构建属性?

我需要从项目外部的位置读取和过滤属性文件,比如$ {user.home} /my.properties。 此属性文件如下所示:

res.dir=/my/stuff/here resource.dir=C:/${res.dir} bin.dir=${resource.dir}/bin cfg.dir=${resource.dir}/config 

我必须在我的构建和运行时的应用程序中执行此操作。 使用PROPERTY标记在Ant中很容易做到这一点。 但是,在Maven中似乎没有一个好方法。

到目前为止,我已经尝试了Maven 标记,Maven 标记以及其他标记的各种排列。 我的构建失败或unit testing失败,或两者兼而有之。

如果我将这些属性硬编码到POM中,一切正常,所以我知道问题只是阅读属性。

我查看了properties-maven-plugin,但插件似乎不再被维护。

有没有办法做到这一点?

您可以简单地实现自己的maven-plugin ,它将为您解决此问题。

以下是具有以下结构的示例:

 . |-- pom.xml |-- plugin | `-- pom.xml | `-- src | `-- main | `-- java `-- app `-- pom.xml `-- src `-- main `-- java 

您需要创建一个Mojo,将属性文件作为输入,然后将属性传播到apppom.xml 。 实际上不会更新pom.xml只会更新其中的项目数据。

pom.xml

  4.0.0 com.stackoverflow Q12082277 1.0-SNAPSHOT pom ${project.artifactId}-${project.version}  plugin app   

plugin/pom.xml

  4.0.0  com.stackoverflow Q12082277 1.0-SNAPSHOT  Q12082277-plugin maven-plugin ${project.artifactId}-${project.version}   org.apache.maven maven-plugin-api 3.0.4   org.apache.maven maven-project 2.2.1    

plugin/src/main/java/com/stackoverflow/Q12082277/plugin/PropertiesMojo.java

 package com.stackoverflow.Q12082277.plugin; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Properties; /** * @author maba, 2012-08-24 * * @goal extract */ public class PropertiesMojo extends AbstractMojo { private Log log; /** * The current project representation. * @parameter expression="${project}" * @required * @readonly */ private MavenProject project; /** * A properties file * * @parameter expression="${propertiesFile}" * @required */ private File propertiesFile; @Override public void execute() throws MojoExecutionException, MojoFailureException { log.info("Executing PropertiesMojo on " + propertiesFile.getAbsolutePath()); try { Properties fileProperties = new Properties(); fileProperties.load(new FileInputStream(propertiesFile)); Properties projectProperties = project.getProperties(); for (Object key : fileProperties.keySet()) { projectProperties.setProperty((String)key, (String) fileProperties.get(key)); } project.getProperties().list(System.out); } catch (FileNotFoundException e) { throw new MojoFailureException("The file " + propertiesFile.getAbsolutePath() + " was not found!", e); } catch (IOException e) { log.error(""); } } @Override public void setLog(Log log) { this.log = log; } } 

您将使用以下app/pom.xml此插件

  4.0.0  com.stackoverflow Q12082277 1.0-SNAPSHOT  Q12082277-app ${project.artifactId}-${project.version}    com.stackoverflow Q12082277-plugin 1.0-SNAPSHOT   initialize  extract   ${user.home}/my.properties      org.codehaus.mojo exec-maven-plugin 1.2.1    java     com.stackoverflow.Q12082277.App      src/main/resources true     

然后你将不得不添加以下app.properties作为模板,并获取我们刚刚从文件中读取的值并设置它们并创建一个可以在jar中访问的具体文件app.properties

app/src/main/resources/app.properties

 res.dir=${res.dir} resource.dir=${resource.dir} bin.dir=${bin.dir} cfg.dir=${cfg.dir} 

最后这里是一个测试应用程序, app.properties从类路径加载app.properties并打印结果。

app/src/main/java/com/stackoverflow/Q12082277/App.java

 package com.stackoverflow.Q12082277; import java.io.IOException; import java.io.InputStream; import java.util.Properties; /** * @author maba, 2012-08-23 */ public class App { public static void main(String[] args) throws IOException { ClassLoader loader = App.class.getClassLoader(); InputStream in = loader.getResourceAsStream("app.properties"); Properties properties = new Properties(); properties.load(in); properties.list(System.out); } } 

现在,您可以站在顶级目录中并执行

 mvn install 

然后进入app文件夹并执行

 mvn exec:java 

它会打印出来

 -- listing properties -- resource.dir=C://my/stuff/here cfg.dir=C://my/stuff/here/config bin.dir=C://my/stuff/here/bin res.dir=/my/stuff/here 

这正是你想要的。

我认为如果将属性文件转换为模板文件并使用maven资源过滤从pom.xml获取属性会更好。

简单的设置可能如下所示

pom.xml

  4.0.0 com.stackoverflow Q12082277 1.0-SNAPSHOT ${project.artifactId}-${project.version}  /default/stuff/here ${res.dir} ${resource.dir}/bin ${resource.dir}/config        src/main/resources true     

src/main/resources/app.properties

 res.dir=${res.dir} resource.dir=${resource.dir} bin.dir=${bin.dir} cfg.dir=${cfg.dir} 

src/main/java/com/stackoverflow/Q12082277/App.java

 package com.stackoverflow.Q12082277; import java.io.IOException; import java.io.InputStream; import java.util.Properties; /** * @author maba, 2012-08-23 */ public class App { public static void main(String[] args) throws IOException { ClassLoader loader = App.class.getClassLoader(); InputStream in = loader.getResourceAsStream("app.properties"); Properties properties = new Properties(); properties.load(in); properties.list(System.out); } } 

System.out

 -- listing properties -- resource.dir=/default/stuff/here cfg.dir=/default/stuff/here/config bin.dir=/default/stuff/here/bin res.dir=/default/stuff/here 

pom.xml将具有每个人使用的默认属性。

如果要覆盖这些值,请使用输入参数调用maven:

 mvn install -Dres.dir=/my/stuff/here -Dresource.dir="C:/${res.dir}" 

System.out

 -- listing properties -- resource.dir=C://my/stuff/here cfg.dir=C://my/stuff/here/config bin.dir=C://my/stuff/here/bin res.dir=/my/stuff/here 

通过这样做,每个人都可以拥有相同的属性视图,如果你想在自己的机器上运行,你可以覆盖它们。