How to set assembly properties from a file in Maven POM?

I need to read and filter the properties file from a location outside my project, say $ {user.home} /my.properties. This properties file is as follows:

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

I need to do this both in my assembly and in my application when it starts. This is easy to do in Ant using the PROPERTY tag . However, in Maven, there seems to be no good way to do this.

So far I have tried the Maven <property> tag, the Maven <filter> and various permutations of the other tags. Either my build fails, or hardware tests fail, or both.

If I hard-set these properties in the POM, everything works, so I know that the problem is only in reading the properties.

I looked at properties-maven-plugin , but the plugin is no longer supported.

Is there any way to do this?

+7
source share
2 answers

You can simply implement your own maven-plugin , which 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 input and then distributes the properties to pom.xml in the app . pom.xml will not actually be updated, but only 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 need to add the following app.properties , which will work as a template and take the values ​​that we just read from the file, and set them and create a specific app.properties file that will be accessible from inside 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, this is a test application that simply loads app.properties from the class path 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 to the app folder and execute

 mvn exec:java 

And he 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 

This is exactly what you wanted.

+7
source

I think it would be better if you turned the properties file into a template file and took properties from pom.xml using maven resource filtering .

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 

pom.xml will have default properties that are used by everyone.

If you want to override the values, then call maven with input parameters:

 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 

That way, everyone will have the same kind of properties, and you can override them if you want, when you work on your own machine.

+3
source

All Articles