Maven2 property that indicates the parent directory

I have a project with several modules, for example:

main-project/ module1/ module2/ sub-module1/ sub-module2/ sub-module3/ ... module3/ module4/ ... 

I need to define a set of properties (which depend on the environment on which I want to release my project) in Maven2. I will not use <properties> , since there are many properties ... Thus, I use the Maven2 Properties plugin .

Property files are located in the main-project/ directory. How to set the correct directory in the main pom.xml to tell all child entities where to find the properties file?

 <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>properties-maven-plugin</artifactId> <version>1.0-alpha-1</version> <executions> <execution> <phase>initialize</phase> <goals> <goal>read-project-properties</goal> </goals> <configuration> <files> <file>???/env_${env}.properties</file> </files> </configuration> </execution> </executions> </plugin> 

If I installed only <file>env_${env}.properties</file> , then when Maven2 compiles the first module, it will not find the main-project/env_dev.properties . If I installed <file>../env_${env}.properties</file> , then the error will be raised at the parent level or at any level of the submodule ...

+94
properties maven-2
Jun 18 '09 at 12:34
source share
19 answers

Try setting a property in each pom to find the main directory of the project.

In parent:

 <properties> <main.basedir>${project.basedir}</main.basedir> </properties> 

In children:

 <properties> <main.basedir>${project.parent.basedir}</main.basedir> </properties> 

Grandchildren:

 <properties> <main.basedir>${project.parent.parent.basedir}</main.basedir> </properties> 
+145
Jun 19 '09 at 18:34
source share

I found a solution to solve my problem: I am viewing property files with the Groovy Maven plugin.

As my properties file is necessarily located in the current directory, in ../ or in .. / .., I wrote a small Groovy code that checks these three folders.

Here is an excerpt of my pom.xml:

 <!-- Use Groovy to search the location of the properties file. --> <plugin> <groupId>org.codehaus.groovy.maven</groupId> <artifactId>gmaven-plugin</artifactId> <version>1.0-rc-5</version> <executions> <execution> <phase>validate</phase> <goals> <goal>execute</goal> </goals> <configuration> <source> import java.io.File; String p = project.properties['env-properties-file']; File f = new File(p); if (!f.exists()) { f = new File("../" + p); if (!f.exists()) { f = new File("../../" + p); } } project.properties['env-properties-file-by-groovy'] = f.getAbsolutePath(); </source> </configuration> </execution> </executions> </plugin> <!-- Now, I can load the properties file using the new 'env-properties-file-by-groovy' property. --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>properties-maven-plugin</artifactId> <version>1.0-alpha-1</version> <executions> <execution> <phase>initialize</phase> <goals> <goal>read-project-properties</goal> </goals> <configuration> <files> <file>${env-properties-file-by-groovy}</file> </files> </configuration> </execution> </executions> </plugin> 

It works, but I really don't like it.

So, if you have a better solution, feel free to post!

+14
Jun 19 '09 at 9:22 a.m.
source share

Use directory-maven-plugin with target directory .

Unlike other offers:

  • This solution works for multi-module projects.
  • This works whether you are building an entire project or submodule.
  • It works whether you run maven from the root folder or submodule.
  • There is no need to set the relative path property in each submodule!

The plugin allows you to set the property of your choice for the absolute path of any of the project modules. In my case, I installed it in the root module ... In my root pom project:

 <plugin> <groupId>org.commonjava.maven.plugins</groupId> <artifactId>directory-maven-plugin</artifactId> <version>0.1</version> <executions> <execution> <id>directories</id> <goals> <goal>directory-of</goal> </goals> <phase>initialize</phase> <configuration> <property>myproject.basedir</property> <project> <groupId>com.my.domain</groupId> <artifactId>my-root-artifact</artifactId> </project> </configuration> </execution> </executions> </plugin> 

From now on, $ {myproject.basedir} in any pom submodule always has a path to the project root module. And, of course, you can set the property for any module, and not just the root ...

+14
Jun 22 '16 at 10:20
source share

So the problem is that you cannot get the absolute path to the parent directory in maven.

I heard that it was discussed as an anti-pattern , but for every anti-pattern there is a real, legitimate use case, and I'm tired of maven saying that I can only follow their patterns. </rant>

So the work I found is to use antrun. Try this in a child pom.xml:

 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.7</version> <executions> <execution> <id>getMainBaseDir</id> <phase>validate</phase> <goals> <goal>run</goal> </goals> <configuration> <exportAntProperties>true</exportAntProperties> <target> <!--Adjust the location below to your directory structure --> <property name="main.basedir" location="./.." /> <echo message="main.basedir=${main.basedir}"/> </target> </configuration> </execution> </executions> </plugin> 

If you run mvn verify , you will see something like this:

 main: [echo] main.basedir=C:\src\parent.project.dir.name 

Then you can use ${main.basedir} in any of the other plugins, etc. It took me a while to figure this out, so hope this helps someone else.

+11
Aug 29 '12 at 19:07
source share

In my case, it works as follows:

 ... <properties> <main_dir>${project.parent.relativePath}/..</main_dir> </properties> ... <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>properties-maven-plugin</artifactId> <version>1.0-alpha-1</version> <executions> <execution> <phase>initialize</phase> <goals> <goal>read-project-properties</goal> </goals> <configuration> <files> <file>${main_dir}/maven_custom.properties</file> </files> </configuration> </execution> </executions> </plugin> 
+6
Oct 25 '12 at 12:33
source share

The following small profile worked for me. I need such a configuration for CheckStyle, which I entered in the config directory in the root of the project, so I can run it from the main module and from submodules.

 <profile> <id>root-dir</id> <activation> <file> <exists>${project.basedir}/../../config/checkstyle.xml</exists> </file> </activation> <properties> <project.config.path>${project.basedir}/../config</project.config.path> </properties> </profile> 

It will not work for nested modules, but I am sure that it can be changed for this, using several profiles with different exists . (I donโ€™t know why the verification tag should have "../ .." in the verification tag and just ".."), but it only works that way.)

+6
Jul 02 '13 at
source share

Another alternative:

in the parent pomp use:

 <properties> <rootDir>${session.executionRootDirectory}</rootDir> <properties> 

In child poms you can refer to this variable.

The main caveat: it forces you to always execute a command from the main pom parent directory. Then, if you want to run commands (for example, test) only for a specific module, use this syntax:

mvn test --projects

The configuration of the correct parameter for parameterizing the variable "path_to_test_data" can then be:

 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>${surefire.plugin.version}</version> <configuration> <systemPropertyVariables> <path_to_test_data>${rootDir}/../testdata</path_to_test_data> </systemPropertyVariables> </configuration> </plugin> 
+5
Oct 20 '15 at 15:58
source share

I found a solution to solve this problem: use $ {parent.relativePath}

 <parent> <artifactId>xxx</artifactId> <groupId>xxx</groupId> <version>1.0-SNAPSHOT</version> <relativePath>..</relativePath> </parent> <build> <filters> <filter>${parent.relativePath}/src/main/filters/filter-${env}.properties</filter> </filters> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build> 
+3
Jul 13 '12 at 15:57
source share

You are in project C, project C is a submodule of B, and B is a submodule of A. You are trying to get to the directory D src/test/config/etc from project C. D is also a submodule of A. The following expression makes this possible to get the URI path:

 -Dparameter=file:/${basedir}/../../D/src/test/config/etc 
+3
Nov 16 '12 at 20:41
source share
 <plugins> <plugin> <groupId>org.codehaus.groovy.maven</groupId> <artifactId>gmaven-plugin</artifactId> <version>1.0</version> <executions> <execution> <phase>validate</phase> <goals> <goal>execute</goal> </goals> <configuration> <source> import java.io.File project.properties.parentdir = "${pom.basedir}" while (new File(new File(project.properties.parentdir).parent, 'pom.xml').exists()) { project.properties.parentdir = new File(project.properties.parentdir).parent } </source> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>properties-maven-plugin</artifactId> <version>1.0-alpha-2</version> <executions> <execution> <phase>initialize</phase> <goals> <goal>read-project-properties</goal> </goals> <configuration> <files> <file>${parentdir}/build.properties</file> </files> </configuration> </execution> </executions> </plugin> ... 
+2
Sep 17 '09 at 12:06
source share

In answer to another question, I showed how the maven-properties-plugin extension can be expanded to use external property descriptors defined in Maven dependencies.

You can extend this idea to have several descriptors, each of which has an environment name as part of artifactId containing $ {env} .properties. Then you can use the property to select the appropriate jar and properties file, for example:

 <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>properties-ext-maven-plugin</artifactId> <version>0.0.1</version> <executions> <execution> <id>read-properties</id> <phase>initialize</phase> <goals> <goal>read-project-properties</goal> </goals> </execution> </executions> <configuration> <filePaths> <!--assume the descriptor project has a file in the root of the jar --> <filePath>${env}.properties</filePath> </filePaths> </configuration> <dependencies> <!-- reference the properties jar for the particular environment--> <dependency> <groupId>some.descriptor.group</groupId> <artifactId>env-${env}-descriptor</artifactId> <version>0.0.1</version> </dependency> </dependencies> </plugin> 
+1
Aug 28 '09 at 20:10
source share

I will just improve the groovy script on top to write the property to the root parent properties file:

 import java.io.*; String p = project.properties['env-properties-file'] File f = new File(p) if (f.exists()) { try{ FileWriter fstream = new FileWriter(f.getAbsolutePath()) BufferedWriter out = new BufferedWriter(fstream) String propToSet = f.getAbsolutePath().substring(0, f.getAbsolutePath().lastIndexOf(File.separator)) if (File.separator != "/") { propToSet = propToSet.replace(File.separator,File.separator+File.separator+File.separator) } out.write("jacoco.agent = " + propToSet + "/lib/jacocoagent.jar") out.close() }catch (Exception e){ } } String ret = "../" while (!f.exists()) { f = new File(ret + p) ret+= "../" } project.properties['env-properties-file-by-groovy'] = f.getAbsolutePath() 
+1
Dec 27 '11 at 9:01 a.m.
source share

I accessed the directory above using $ {basedir} .. \ src \

+1
Apr 15 '16 at 2:06
source share

Have you tried ../../env_${env}.properties ?

Usually we do the following when module2 is at the same level as submodules

 <modules> <module>../sub-module1</module> <module>../sub-module2</module> <module>../sub-module3</module> </modules> 

I would think that .. / .. will allow you to jump into two levels. If not, you can refer to the plugin in the authors and find out if this is a known issue.

0
Jun 18 '09 at 16:16
source share

I think that if you use the extension template used in the example for the findbugs and multimodule plugin, you can set global properties associated with absolute paths. He uses the top

example for several modules

The top-level pom has an unrelated build-config project and a parent application for project modules with multiple modules. The parent application uses the extension to associate itself with the build-config project and get resources from it. This is used to transfer common configuration files to modules. This may be a channel for properties. You could write the top directory to the properties file consumed by build-config. (seems too complicated)

The problem is that a new new level needs to be added to the multi-module project to make this work. I tried to take a side step with a really unrelated build-config project, but it was shredded and seemed fragile.

0
Sep 18 '09 at 20:31
source share

This extends the romaintaz request, which is surprising in that it solves the problem and also clearly indicates the absence of the maven function. I took a later version of the plugin and added a case where a project can have more than three levels.

 <pluginManagement> <plugins> .. <plugin> <groupId>org.codehaus.gmaven</groupId> <artifactId>groovy-maven-plugin</artifactId> <version>2.0</version> </plugin> .. </plugins> </pluginManagement> 

I decided not to use the property to determine the file name. Note that if build.properties is not found, it will spin forever. I added the .git dir detector, but did not want it to complicate the answer, so it is not shown here.

  <plugin> <groupId>org.codehaus.gmaven</groupId> <artifactId>groovy-maven-plugin</artifactId> <executions> <execution> <phase>validate</phase> <goals> <goal>execute</goal> </goals> <configuration> <source> import java.io.File; String p = "build.properties"; while(true) { File f = new File(p); if(f.exists()) { project.properties['project-properties-file'] = f.getAbsolutePath(); break; } else { p = "../${p}"; } } </source> </configuration> </execution> </executions> </plugin> 
0
08 Sep '15 at 19:21
source share

I needed to solve a similar problem for a local repository hosted in the main project of a multi-module project. Essentially, the real path was ${basedir} / lib. Finally, I settled on this in my parent.pom :

 <repository> <id>local-maven-repo</id> <url>file:///${basedir}/${project.parent.relativePath}/lib</url> </repository> 

Because basedir always displayed in the current local module, there is no way to get the path to the "master project" (shame on Maven). Some of my submodules are one dir deeper, some of them are two, deeper, but they are all direct submodules of the parent that defines the repo url.

Thus, this does not solve the problem as a whole. You can always combine it with the accepted answer to Clay and define some other property - it works fine and needs to be redefined only for cases when the value from parent.pom not good enough. Or you can simply reconfigure the plugin that you only do in POM artifacts (parents of other submodules). The value extracted to the property is probably better if you need it in more places, especially when nothing in the plugin configuration changes.

Using basedir in the value was an essential part here because the URL file://${project.parent.relativePath}/lib did not want to do the trick (I removed one slash to make it relative). Using a property that gives me a good absolute path, and then moving from it was necessary.

When the path is not a URL / URI, perhaps it is not such a problem to abandon basedir .

0
Oct 13 '15 at 15:57
source share

At least in the current version of maven (3.6.0) you can use ${maven.multiModuleProjectDirectory}

0
Mar 28 '19 at 16:11
source share

The first answer should work. In the inheritance line, the parent-then custom property set using the maven-default property in the top-level POM (in this case <parent.base.directory>${project.parent.basedir}</parent.base.directory> ) will be set when it crosses a tree. In other words, ${parent.base.directory} will be set correctly in another child POM.

Note. You should not use ${parent.basedir} as your user-defined property, as it matches the maven-default ${project.parent.basedir} property. Otherwise, it gets a recursive expression error in maven. Therefore, I use ${parent.base.directory} in the answer.

Hope this is a radical solution to the problem.

-one
Jul 24 '16 at 15:00
source share



All Articles