62

In a multi-module maven project, is there a variable that points to the root project folder?

  • ${project.basedir} points to the current project's directory,
  • ${project.parent.basedir} points to the parent project's directory,

but is there a variable that always points to the root directory (the one from which the maven command was executed), no matter from which project inside the reactor?


I realized that the problem I wanted to solve is pretty much unsolvable. I wanted a variable that pointed to either project.basedir, project.parent.basedir, project.parent.parent.basedir etc, whichever is higher. But since a project's parent pom need not be it's parent in the file system, my whole approach won't help. So I am accepting Pascal's answer because it answers my question (even if my question does not solve my problem).

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • But anyway it is disturbing, that if we would have created it, there would be such variable :( – Gábor Lipták Nov 11 '10 at 13:42
  • Possible duplicate of [Finding the root directory of a multi module maven reactor project](http://stackoverflow.com/questions/3084629/finding-the-root-directory-of-a-multi-module-maven-reactor-project) – sschuberth Apr 17 '17 at 13:40

7 Answers7

46

is there a variable that always points to the root directory (the one from which the maven command was executed)

user.dir (the working directory) should be that directory.

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
40

In the latest maven, you can use ${maven.multiModuleProjectDirectory}.

Alex Shesterov
  • 26,085
  • 12
  • 82
  • 103
Mateusz Stefek
  • 3,478
  • 2
  • 23
  • 28
  • 2
    With Maven 3.6.3 I determined, with the plugin goal configured in the submodule pom.xml, this will reference the module dir from which maven is run. If running in development from a submodule dir it will not "reference upwards" as one might hope. It is sufficient for most purposes, however. – Ed Randall Jan 09 '21 at 10:51
  • 3
    If a ".mvn" directory (which may be empty) exists in the root of the multimodule project, this works 100% (again, with 3.6.3) – Ed Randall Jan 09 '21 at 10:56
24

In Maven 3, ${session.executionRootDirectory} is "a variable that always points to the ... directory ... from which the maven command was executed."

Note that this is distinct from a property that gives the top-level root directory of a multi-module project, regardless of where in the directory structure mvn is executed from. Such a property does not exist to my knowledge, but you can use the ${basedir}/.. hack to achieve it. See this thread on maven-users for more details.

See also: Finding the root directory of a multi module maven reactor project

Community
  • 1
  • 1
ctrueden
  • 6,751
  • 3
  • 37
  • 69
7

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 (unlike ${session.executionRootDirectory}
  • 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...

Gama11
  • 31,714
  • 9
  • 78
  • 100
sparkyd
  • 550
  • 6
  • 6
5

Such property can be created using: directory-maven-plugin. Using the plugin's highest-basedir goal you can assign the root path to any property you specify.

Andrejs
  • 26,885
  • 12
  • 107
  • 96
5

For me, there was a need for root directory during variable interpolation, not for plugins section - for local directory relative to root with hand-crafted jars. I know this is a bad practice to have local directory with jars, but this was a requirement of project.

Why I was unable to use different solutions:

  • ${session.executionRootDirectory} and ${user.dir} are tied with directory from which maven command was executed. I want to refer to the same directory independently of directory, from which maven was launched.
  • ${project.basedir} ,as mentioned above, points to current project directory, so child modules will search for jars in wrong location.
  • I had about 100 projects, so defining relative paths or usage of accepted answer for this question is quite complex in my case.
  • Directory plugin can be used only for plugin configurations, not for variable interpolation

So, in my case with bad requirements I have used environment variable which refers project root and used it in pom.xml. Use it as last resort, when other solutions do not work. Here is example, how I use environment variable in my case:

<repositories>
    <repository>
        <id>local-maven-repo</id>
        <!--NOTE: export PROJECT_ROOT=<location>-->
        <url>file:///${env.PROJECT_ROOT}/local-repo</url>
    </repository>
</repositories>
Community
  • 1
  • 1
Mikalai Parafeniuk
  • 1,328
  • 15
  • 10
2

As far I think, there is no such variable. There are only workaround like in accepted answer of Maven2 property that indicates the parent directory .

Community
  • 1
  • 1
Gábor Lipták
  • 9,646
  • 2
  • 59
  • 113