如何从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,将属性文件作为输入,然后将属性传播到app
的pom.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
通过这样做,每个人都可以拥有相同的属性视图,如果你想在自己的机器上运行,你可以覆盖它们。