Joseph Thomas-Kerr
Joseph Thomas-Kerr

Reputation: 339

Maven POM: how to insist property is not overridden

I have a parent POM that uses a gmaven script to do some stuff:

   <plugin>
      <groupId>org.codehaus.gmaven</groupId>
      <artifactId>gmaven-plugin</artifactId>
      <version>1.4</version>

      <configuration combine.children="override">
        <providerSelection>2.0</providerSelection>
        <scriptPath>${basedir}/build/groovy</scriptPath>
      </configuration>
      <executions>
        <execution>
          <id>groovy-properties-script</id>
          <phase>validate</phase>
          <goals>
            <goal>execute</goal>
          </goals>
          <configuration>
            <source>computeProperties.groovy</source>
          </configuration>
        </execution>
          <!-- ... -->

All of the children are supposed to run this script as well, but they try to resolve the scriptpath based on their OWN basedir. Usually this is exactly what you want with properties, but here it doesn't work, and I can't figure out any way around it.

Upvotes: 3

Views: 2129

Answers (2)

maba
maba

Reputation: 48055

The best way to do these kind of things is to put your groovy scripts in its own jar file and have maven-dependency-plugin unpack it for you. Then your script can point to the unpacked script.

Like this example:

directory layout

+- pom.xml
  +- script
  | +- pom.xml
  | +- src
  |   +- main
  |     +- resources
  |       +-computeProperties.groovy
  +- code
    +- pom.xml
    +- src
      +- main
        +- java

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.stackoverflow</groupId>
    <artifactId>Q11321971</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <name>${project.artifactId}-${project.version}</name>

    <properties>
    </properties>

    <modules>
        <module>script</module>
        <module>code</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <!-- Inter-Module dependencies -->
            <dependency>
                <groupId>com.stackoverflow</groupId>
                <artifactId>Q11321971-script</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-dependency-plugin</artifactId>
                    <version>2.4</version>
                    <executions>
                        <execution>
                            <id>unpack</id>
                            <phase>validate</phase>
                            <goals>
                                <goal>unpack</goal>
                            </goals>
                            <configuration>
                                <artifactItems>
                                    <artifactItem>
                                        <groupId>com.stackoverflow</groupId>
                                        <artifactId>Q11321971-script</artifactId>
                                        <overWrite>false</overWrite>
                                        <outputDirectory>${project.build.directory}/build/groovy</outputDirectory>
                                        <includes>**/*.groovy</includes>
                                    </artifactItem>
                                </artifactItems>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

script/pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.stackoverflow</groupId>
        <artifactId>Q11321971</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>Q11321971-script</artifactId>

    <name>${project.artifactId}-${project.version}</name>

</project>

code/pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.stackoverflow</groupId>
        <artifactId>Q11321971</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>Q11321971-code</artifactId>

    <name>${project.artifactId}-${project.version}</name>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-dependency-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

If you run this top pom you will find that in the target directory of the code module there is now build/groovy/computeProperties.groovy that you can refer to in your plugin.

This will work from all modules even for the parent pom by adding this to the <build/> tag of the parent:

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-dependency-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

The parent will now have a target directory with build/groovy/computeProperties.groovy in it.

In your plugin you can change the <scriptPath/> to this:

<scriptPath>${project.build.directory}/build/groovy</scriptPath>

And since the maven-dependency-plugin is now running in the validate phase then the gmaven-plugin must run in a later phase. That is something that you can elaborate like you want.

The very good thing about doing it this way is that if someone only wants to check out a child module then they can run it and the script jar will be downloaded from the repo and being used.

No relative paths needed...

Upvotes: 0

Joseph Thomas-Kerr
Joseph Thomas-Kerr

Reputation: 339

One way around this seems to be to use the set-system-properties goal of the properties-maven-plugin, thusly:

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>properties-maven-plugin</artifactId>
    <version>1.0-alpha-2</version>
    <inherited>false</inherited>
    <executions>
      <execution>
        <goals>
          <goal>set-system-properties</goal>
        </goals>
        <configuration>
          <properties>
            <property>
              <name>com.binu.core.parent.basedir</name>
              <value>${basedir}</value>
            </property>
          </properties>
        </configuration>
      </execution>
    </executions>
  </plugin>

Because it is not inherited, this plugin will only run in the parent pom. This seems rather hacky though, is there a native maven way to achieve this?

Upvotes: 1

Related Questions