1

How to construct the path to a resource used during the build (specifically the verify phase), so it will be found whether maven was executed on the reactor root or on the child module directly?

Project Files

UniBldResLocPrb/pom.xml # Reactor/Aggregation POM

UniBldResLocPrb/modules/parent/pom.xml
UniBldResLocPrb/modules/parent/src/main/resources/javaHeaderRegexTemplate.txt
UniBldResLocPrb/modules/parent/src/main/resources/checkstyle.xml

UniBldResLocPrb/modules/child/pom.xml

Scenario

I need to insert the path to a resource (javaHeaderRegexTemplate.txt) - absolute or relative to the maven execution CWD - into an other resource (checkstyle.xml). This is configured in parent/pom.xml. This path (relative, because i do not know how to get it as absolute) changes depending on whether i build the child project directly, or through the reactor.

correct paths:

  • child build: ../parent/src/main/resources/javaHeaderRegexTemplate.txt
  • reactor build: modules/parent/src/main/resources/javaHeaderRegexTemplate.txt

I am not able to configure my POMs so both of these builds work without problem.

It works without problem when building the child directly:

cd UniBldResLocPrb/modules/child/
mvn verify
    [INFO] BUILD SUCCESS

But it fails when building through the reactor POM:

cd UniBldResLocPrb/
mvn verify
    [INFO] BUILD FAILURE
    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:2.15:check (default) on project myproj-child: Failed during checkstyle configuration: cannot initialize module RegexpHeader - unable to load header file ../parent/src/main/resources/javaHeaderRegexTemplate.txt -> [Help 1]

If i manually set <root.basedir>modules/parent</root.basedir> in the child POM, then only the reactor build succeeds, while the child build fails.

This question comes closest to mine: Maven Project Aggregation and Variables But the accepted answer does not apply, because the profile activation checking the file always uses the child project as CWD, even if the maven execution CWD is that of the reactor project.

I am testing with Maven 3.0.5.

Example Project sources

I made a minimal example, showing what i tried and how it fails.

GitHub Project: https://github.com/ProblemExamples/UniBldResLocPrb

or:

git clone https://github.com/ProblemExamples/UniBldResLocPrb.git

Important parts of the sources (as on github)

UniBldResLocPrb/pom.xml:

    <properties>
        <!-- NOTE This will be overwritten by the child module. -->
        <root.basedir>modules/parent</root.basedir>
    </properties>

UniBldResLocPrb/modules/child/pom.xml:

    <properties>
        <!--
            NOTE This is alwasy in effect, but it is only valid if maven is executed
            on this POM directly.
        -->
        <root.basedir>${project.parent.relativePath}</root.basedir>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-checkstyle-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <!-- Execute during the maven "verify" phase (`mvn verify`) -->
                            <goal>check</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

UniBldResLocPrb/modules/parent/src/main/resources/checkstyle.xml:

    <!-- NOTE the used variable is supplied by the invocation in maven! -->
    <module name="RegexpHeader">
        <property name="headerFile" value="${java.header.regex.template.file}"/>
    </module>

UniBldResLocPrb/modules/parent/pom.xml:

    <properties>
        <!--
            NOTE This would be overwritten by the child module,
            so it has no effect in this particular example project,
            as we do not use this variable in this POM during the build.
        -->
        <!--<root.basedir>${project.basedir}</root.basedir>-->
    </properties>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-checkstyle-plugin</artifactId>
                    <version>2.15</version>
                    <configuration>
                        <configLocation>src/main/resources/checkstyle.xml</configLocation>
                        <propertyExpansion>java.header.regex.template.file=${root.basedir}/src/main/resources/javaHeaderRegexTemplate.txt</propertyExpansion>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
Community
  • 1
  • 1
hoijui
  • 3,615
  • 2
  • 33
  • 41
  • true, thanks! i reduced the sources i show in the post. – hoijui Aug 02 '15 at 19:26
  • 1
    See [Vic's answer](http://stackoverflow.com/a/17423568/1744774) to [Maven2 property that indicates the parent directory](http://stackoverflow.com/questions/1012402/maven2-property-that-indicates-the-parent-directory) where he uses a [Build Profile](https://maven.apache.org/guides/introduction/introduction-to-profiles.html) with CheckStyle. – Gerold Broser Aug 02 '15 at 20:59

1 Answers1

1

I ended up setting only this single property in the parent POM.

<properties>
    <!-- NOTE This works for reactor/aggregation & child module builds. -->
    <root.basedir>${project.basedir}/../parent</root.basedir>
</properties>

This works because ${project.basedir} seems to expand to an absolute path, and always the one to the actual project being built, even if maven is executed on the reactor POM. In my case, the projects to build (which will use the ${root.basedir} property) will always be a child project. They are all located under "modules/", so going "../parent" from their path works fine.

${root.basedir} will contain something like:

"/home/user/projects/UniBldResLocPrb/modules/child/../parent"

Thanks to users Gerold Broser and Vic for leading me to this answer.

hoijui
  • 3,615
  • 2
  • 33
  • 41