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
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
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;
}
}
You will use this plugin from the following 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
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.