如何从 Maven POM 中的文件设置构建属性? [英] How to set build properties from a file in Maven POM?

查看:20
本文介绍了如何从 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,它将属性文件作为输入,然后将属性传播到 apppom.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆