Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

maven change properties on the fly (runtime)

I am having the following problem: I want to be able to change maven properties on the fly using a plugin. for instance if i have a property configured such as:

<properties>
   <someProperty>value</someProperty>
</properties>

i want to have a way to change it to "value-2" during the maven run itself (not before! for instance, i do not want to use -DsomeProperty=value-2 at command line)

I will try to explain my use case to clarify: My pom.xml has some default properties set. However, i am running a task that creates a property file with name=value pairs to match my properties (for instance, if i have a property such as someProperty=value in my pom.xml the run.properties file has someProperty=value-2 property). during some maven run i would like to pass it the location of my properties file and have it change the default properties in my pom.xml. I have tried using the "properties-maven-plugin" to achieve this goal but this only seems to work if i do not have the property configured in the pom.xml itself. That is, if the section in my pom.xml does not have the "someProperty" property then the change works successfully. If i do have it, however then no change is made and i want to be able to change it even if some property is defined in the pom.xml

Any suggestions? thanks in advance

like image 665
ShinySpiderdude Avatar asked Jul 02 '13 12:07

ShinySpiderdude


2 Answers

I've been playing with gmavenplus-plugin which replaces the older gmaven-plugin. In this example, I'm trying to conditionally direct the upload of docker images to either a SNAPSHOT and RELEASE docker registry similar to how the maven-deploy-plugin works. With this code, I parse the version and set a property pointing to the correct repo. Once you get into groovy you can mess around with maven like you are a regular java implemented maven plugin.

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>1.10</version>
    <executions>
      <execution>
        <id>parse-version</id>
        <goals>
          <goal>parse-version</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

  <plugin>
    <groupId>org.codehaus.gmavenplus</groupId>
    <artifactId>gmavenplus-plugin</artifactId>
    <version>1.5</version>
    <dependencies>
      <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>2.4.4</version>
        <scope>runtime</scope>
      </dependency>
      <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.0.13</version>
        <scope>runtime</scope>
      </dependency>
    </dependencies>
    <executions>
      <execution>
        <id>add-dynamic-properties</id>
        <phase>initialize</phase>
        <goals>
          <goal>execute</goal>
        </goals>
        <configuration>
          <scripts>
            <script>
<![CDATA[
import java.text.SimpleDateFormat;

Date now = new Date()
SimpleDateFormat timestamp = new SimpleDateFormat("yyyyMMdd.HHmmss");

myver  = "${project.version}"
myqual = "${parsedVersion.qualifier}"
myrepo = (myqual == "SNAPSHOT") ? "${docker.repo.snapshot}" : "${docker.repo.release}"
mytag  = (myqual == "SNAPSHOT") ? myver + "-" + timestamp.format(now) : myver

project.properties.setProperty('docker.repo.name', myrepo)
project.properties.setProperty('docker.image.tag', mytag) 

log.info("Docker repository name is " + project.properties['docker.repo.name'])
log.info("Docker image tag is " + project.properties['docker.image.tag'])
]]>
            </script>
          </scripts>
        </configuration>
      </execution>
    </executions>
  </plugin>
like image 92
Stagr.Lee Avatar answered Sep 23 '22 05:09

Stagr.Lee


As you found out, you cannot use dynamically changed value of property defined in POM's properties section. If you want to know why, read this answer to the end.

In order to use dynamic values and default values you have to set default values dynamically. You can use GMaven plugin for this and configure it probably as a first plugin in build. See Guillaume Darmont's answer.

And here is the explanation why this is needed. Maven replaces property values two times:

  1. at the beginning (probably during assembling of effective POM) it replaces static properties (declared in properties sections)
  2. before each run of a plugin it replaces properties again so dynamic values used now

What the above means is that if you have static declaration <myProperty> and later you use this property like ${myProperty} the value is injected before you have a chance to dynamicaly change it. Later you can dynamicaly change the value but the placeholder is already replaced so the dynamic value is nowhere to be injected.

I also answered this behavior here, maybe it is better explained there for someone.

like image 43
Mrkvozrout Avatar answered Sep 20 '22 05:09

Mrkvozrout