[英]How to set build properties from a file in Maven POM?
I need to read and filter a properties file from a location outside my project, say ${user.home}/my.properties. 我需要从项目外部的位置读取和过滤属性文件,比如$ {user.home} /my.properties。 This properties file looks like this:
此属性文件如下所示:
res.dir=/my/stuff/here
resource.dir=C:/${res.dir}
bin.dir=${resource.dir}/bin
cfg.dir=${resource.dir}/config
I have to do this in both my build and in my application when it runs. 我必须在我的构建和运行时的应用程序中执行此操作。 This is easy to do in Ant, using the PROPERTY tag .
使用PROPERTY标记在Ant中很容易做到这一点。 However, there doesn't seem to be a good way to do it in Maven.
但是,在Maven中似乎没有一个好的方法。
So far I have tried the Maven <property>
tag, the Maven <filter>
tag and various permutations of other tags. 到目前为止,我已经尝试了Maven
<property>
标记,Maven <filter>
标记以及其他标记的各种排列。 Either my build fails or the unit tests fail, or both. 我的构建失败或单元测试失败,或两者兼而有之。
If I hardcode these properties into the POM, everything works, so I know the problem is just reading the properties. 如果我将这些属性硬编码到POM中,一切正常,所以我知道问题只是阅读属性。
I looked at the properties-maven-plugin but the plugin no longer seems to be maintained. 我查看了properties-maven-plugin,但插件似乎不再被维护。
Is there a way to do this? 有没有办法做到这一点?
You could simply implement your own maven-plugin
that will take care of this for you. 你可以简单地实现自己的
maven-plugin
来为你处理这个问题。
Here is an example with the following structure: 以下是具有以下结构的示例:
.
|-- pom.xml
|-- plugin
| `-- pom.xml
| `-- src
| `-- main
| `-- java
`-- app
`-- pom.xml
`-- src
`-- main
`-- java
You will need to create a Mojo that takes the properties file as an input and then propagates the properties to the pom.xml
of the app
. 您需要创建一个Mojo,将属性文件作为输入,然后将属性传播到
app
的pom.xml
。 The pom.xml
will actually not be updated but just the project data in it. 实际上不会更新
pom.xml
只会更新其中的项目数据。
pom.xml
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>Q12082277</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>${project.artifactId}-${project.version}</name>
<modules>
<module>plugin</module>
<module>app</module>
</modules>
</project>
plugin/pom.xml
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.stackoverflow</groupId>
<artifactId>Q12082277</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>Q12082277-plugin</artifactId>
<packaging>maven-plugin</packaging>
<name>${project.artifactId}-${project.version}</name>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.0.4</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>
</project>
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;
}
}
You will use this plugin from the following app/pom.xml
您将使用以下
app/pom.xml
此插件
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.stackoverflow</groupId>
<artifactId>Q12082277</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>Q12082277-app</artifactId>
<name>${project.artifactId}-${project.version}</name>
<build>
<plugins>
<plugin>
<groupId>com.stackoverflow</groupId>
<artifactId>Q12082277-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>extract</goal>
</goals>
<configuration>
<propertiesFile>${user.home}/my.properties</propertiesFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.stackoverflow.Q12082277.App</mainClass>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
And then you will have to add the following app.properties
that will work as a template and take the values that we have just read from file and set them and create a concrete file app.properties
that will be reachable from within the jar. 然后你将不得不添加以下
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}
And finally here is a test application that just loads the app.properties
from the classpath and prints the result. 最后这里是一个测试应用程序,
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);
}
}
Now you can stand in the top directory and execute 现在,您可以站在顶级目录中并执行
mvn install
Then go down into the app
folder and execute 然后进入
app
文件夹并执行
mvn exec:java
And it will print 它会打印出来
-- 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
Which is exactly what you wanted. 这正是你想要的。
I think it would be better if you turned the properties file into a template file and take the properties from the pom.xml
using maven resource filtering . 我认为如果将属性文件转换为模板文件并使用maven资源过滤从
pom.xml
获取属性会更好。
A simple setup might look like this 简单的设置可能如下所示
pom.xml
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>Q12082277</artifactId>
<version>1.0-SNAPSHOT</version>
<name>${project.artifactId}-${project.version}</name>
<properties>
<res.dir>/default/stuff/here</res.dir>
<resource.dir>${res.dir}</resource.dir>
<bin.dir>${resource.dir}/bin</bin.dir>
<cfg.dir>${resource.dir}/config</cfg.dir>
</properties>
<dependencies>
<!-- Your dependencies -->
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
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
The pom.xml
will have the default properties that are used by everybody. pom.xml
将具有每个人使用的默认属性。
If you want to override the values then call maven with input parameters: 如果要覆盖值,则使用输入参数调用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
By doing it this way everybody will have the same view of the properties and you can override them if you want to when running on your own machine. 通过这样做,每个人都可以拥有相同的属性视图,如果你想在自己的机器上运行,你可以覆盖它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.