如何从 Maven POM 中的文件设置构建属性? [英] How to set build properties from a file in Maven POM?
问题描述
我需要从我的项目之外的位置读取和过滤属性文件,比如 ${user.home}/my.properties.此属性文件如下所示:
res.dir=/my/stuff/hereresource.dir=C:/${res.dir}bin.dir=${resource.dir}/bincfg.dir=${resource.dir}/config
当它运行时,我必须在我的构建和我的应用程序中执行此操作.这在 Ant 中很容易做到,使用 PROPERTY 标签.但是,在 Maven 中似乎没有一个好方法.
到目前为止,我已经尝试了 Maven
标签、Maven
标签和其他标签的各种排列.我的构建失败或单元测试失败,或两者兼而有之.
如果我将这些属性硬编码到 POM 中,则一切正常,所以我知道问题只是读取属性.
我查看了 properties-maven-plugin 但该插件似乎不再待维护.
有没有办法做到这一点?
你可以简单地实现你自己的 maven-plugin
来为你解决这个问题.
这是一个具有以下结构的示例:
<预><代码>.|-- pom.xml|-- 插件|`-- pom.xml|`-- 源代码|`--主要|`--java`-- 应用程序`-- pom.xml`-- 源代码`--主要`--java您需要创建一个 Mojo,它将属性文件作为输入,然后将属性传播到 app
的 pom.xml
.pom.xml
实际上不会更新,只会更新其中的项目数据.
pom.xml
<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><模块><模块>插件</模块><module>app</module></模块></项目>
plugin/pom.xml
<modelVersion>4.0.0</modelVersion><父母><groupId>com.stackoverflow</groupId><artifactId>Q12082277</artifactId><version>1.0-SNAPSHOT</version></父母><artifactId>Q12082277-plugin</artifactId><packaging>maven-plugin</packaging><name>${project.artifactId}-${project.version}</name><依赖项><依赖><groupId>org.apache.maven</groupId><artifactId>maven-plugin-api</artifactId><version>3.0.4</version></依赖><依赖><groupId>org.apache.maven</groupId><artifactId>maven-project</artifactId><version>2.2.1</version></依赖></依赖项></项目>
plugin/src/main/java/com/stackoverflow/Q12082277/plugin/PropertiesMojo.java
package com.stackoverflow.Q12082277.plugin;导入 org.apache.maven.plugin.AbstractMojo;导入 org.apache.maven.plugin.MojoExecutionException;导入 org.apache.maven.plugin.MojoFailureException;导入 org.apache.maven.plugin.logging.Log;导入 org.apache.maven.project.MavenProject;导入 java.io.File;导入 java.io.FileInputStream;导入 java.io.FileNotFoundException;导入 java.io.IOException;导入 java.util.Properties;/*** @作者马巴,2012-08-24** @目标摘录*/公共类 PropertiesMojo 扩展 AbstractMojo {私人日志日志;/*** 当前的项目代表.* @parameter 表达式="${project}"* @必需的* @只读*/私有MavenProject项目;/*** 一个属性文件** @parameter 表达式="${propertiesFile}"* @必需的*/私有文件属性文件;@覆盖public void execute() 抛出 MojoExecutionException, MojoFailureException {log.info("在" + propertiesFile.getAbsolutePath()) 上执行 PropertiesMojo;尝试 {属性 fileProperties = new Properties();fileProperties.load(new FileInputStream(propertiesFile));属性 projectProperties = project.getProperties();for (对象键:fileProperties.keySet()) {projectProperties.setProperty((String)key, (String) fileProperties.get(key));}project.getProperties().list(System.out);} catch (FileNotFoundException e) {throw new MojoFailureException("文件" + propertiesFile.getAbsolutePath() + " 未找到!", e);} catch (IOException e) {日志错误(");}}@覆盖public void setLog(日志日志){this.log = 日志;}}
您将从以下 app/pom.xml
<modelVersion>4.0.0</modelVersion><父母><groupId>com.stackoverflow</groupId><artifactId>Q12082277</artifactId><version>1.0-SNAPSHOT</version></父母><artifactId>Q12082277-app</artifactId><name>${project.artifactId}-${project.version}</name><构建><插件><插件><groupId>com.stackoverflow</groupId><artifactId>Q12082277-plugin</artifactId><version>1.0-SNAPSHOT</version><执行><执行><相位>初始化</相位><目标><目标>提取</目标></目标><配置><propertiesFile>${user.home}/my.properties</propertiesFile></配置></执行></执行></插件><插件><groupId>org.codehaus.mojo</groupId><artifactId>exec-maven-plugin</artifactId><version>1.2.1</version><执行><执行><目标><目标>java</目标></目标></执行></执行><配置><mainClass>com.stackoverflow.Q12082277.App</mainClass></配置></插件></plugins><资源><资源><目录>src/main/resources</directory><filtering>true</filtering></资源></资源></build></项目>
然后您必须添加以下 app.properties
它将用作模板并获取我们刚刚从文件中读取的值并设置它们并创建一个具体文件 app.properties
可以从 jar 中访问.
app/src/main/resources/app.properties
res.dir=${res.dir}资源.dir=${resource.dir}bin.dir=${bin.dir}cfg.dir=${cfg.dir}
最后是一个测试应用程序,它只从类路径加载 app.properties
并打印结果.
app/src/main/java/com/stackoverflow/Q12082277/App.java
package com.stackoverflow.Q12082277;导入 java.io.IOException;导入 java.io.InputStream;导入 java.util.Properties;/*** @author maba, 2012-08-23*/公共类应用{public static void main(String[] args) 抛出 IOException {ClassLoader 加载器 = App.class.getClassLoader();InputStream in = loader.getResourceAsStream("app.properties");属性 properties = new Properties();properties.load(in);属性列表(系统输出);}}
现在可以站在顶层目录执行
mvn 安装
然后进入app
文件夹并执行
mvn exec:java
它会打印
-- 列出属性--resource.dir=C://my/stuff/herecfg.dir=C://my/stuff/here/configbin.dir=C://my/stuff/here/binres.dir=/my/stuff/here
这正是您想要的.
I need to read and filter a properties file from a location outside my project, say ${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. However, there doesn't seem to be a good way to do it in Maven.
So far I have tried the Maven <property>
tag, the Maven <filter>
tag and various permutations of other tags. 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.
I looked at the properties-maven-plugin but the plugin no longer seems to be maintained.
Is there a way to do this?
You could simply implement your own maven-plugin
that will take care of this for you.
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
. The pom.xml
will actually not be updated but just the project data in it.
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
<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/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/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
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.
这篇关于如何从 Maven POM 中的文件设置构建属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!