Maven2 property that indicates the parent directory

I have a multi-modules project, like this one:

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

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

The properties files are located in the main-project/ directory. How can I set the correct directory in the main pom.xml, in order to specify to any children 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 set only <file>env_${env}.properties</file>, then when Maven2 compiles the first module, it will not find the main-project/env_dev.properties file. If I set <file>../env_${env}.properties</file>, then an error will be raised at the parent level, or at any sub-module level...


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

In the parent:

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

In the children:

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

In the grandchildren:

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

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


Use directory-maven-plugin with directory-of goal.

Unlike other suggestions:

  • This solution works for multi-module projects.
  • It works whether you build the whole project or a sub-module.
  • It works whether you run maven from the root folder or a sub-module.
  • There's no need to set a relative path property in each and every sub-module!

The plugin lets you set a property of your choice to the absolute-path of any of the project's modules. In my case I set it to the root module... In my project root pom:

<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 then on, ${myproject.basedir} in any sub-module pom always has the path of the project root module. And of course, you can set the property to any module, not just the root...


I've found a solution to solve my problem: I search the properties files using the Groovy Maven plugin.

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

Here is the extract 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>

This is working, but I don't really like it.

So, if you have a better solution, do not hesitate to post!