9

I'd like to set a property if an environment variable is set. I googled a lot on it and all I found is something similar to the code below, but I keep getting the error:

[FATAL] Non-parseable POM Y:\Maven\parent-pom\pom.xml: TEXT must be immediately followed by END_TAG and not START_TAG (position: START_TAG s een ...roperties"\r\n
classpathref="maven.plugin.classpath" />... @29:55) @ line 29, column 55

That's the code I'm trying, its inside a pom.xml and I ran the command -

mvn --errors deploy

Of course, I'll be happy to get any other solution, if you have other suggestion on how to set a property in pom.xml depending on an environment variable content.

Thanks, Eli

    <distributionManagement>
       .....
    </distributionManagement>

    <properties>
          <tasks>
        <taskdef resource="net/sf/antcontrib/antcontrib.properties"
          classpathref="maven.plugin.classpath" />

        <if>
           <condition>
             <equals arg1="${env.WAS60_HOME}" arg2=""\>
           </condition>
           <then>
             <was60.home>${env.WAS60_HOME}</was60.home>
             <javac>${was60.home}/java/bin/javac</javac>
           </then>
        </if>

         <if>
           <condition>
             <equals arg1="${env.WAS85_HOME}" arg2=""\>
           </condition>
           <then>
             <was85.home>${env.WAS85_HOME}</was60.home>
             <javac>${was85.home}/java/bin/javac</javac>
           </then>
        </if>
      </tasks>
</properties>
    <profiles>
       <profile>
    <id>was.base.v60</id>
            <dependencies>
               <dependency>
                 ....
                  <systemPath>${was60.home}/java/jre/lib/xml.jar</systemPath>
               </dependency>
               .....
            </dependencies>
        </profile>
        <profile>
    <id>was.base.v85</id>
            <dependencies>
               <dependency>
                 ....
                  <systemPath>${was85.home}/java/jre/lib/xml.jar</systemPath>
               </dependency>
               .....
            </dependencies>
        </profile>
    </profiles>
NoobEditor
  • 15,563
  • 19
  • 81
  • 112
Elyahu
  • 226
  • 1
  • 2
  • 15

4 Answers4

16

A much better approach would be to use profile activations.

<profiles>
  <profile>
    <id>was.base.v60</id>
    <activation>
      <property>
        <name>env.WAS60_HOME</name>
      </property>
    </activation>
    <dependencies>
      <dependency>
        ....     
        <systemPath>${env.WAS60_HOME}/java/jre/lib/xml.jar</systemPath>
      </dependency>
      .....    
    </dependencies>
  </profile>
  <profile>
    <id>was.base.v85</id>
    <activation>
      <property>
        <name>env.WAS85_HOME</name>
      </property>
    </activation>
    <dependencies>
      <dependency>
        ....     
        <systemPath>${env.WAS85_HOME}/java/jre/lib/xml.jar</systemPath>
      </dependency>
      .....    
    </dependencies>
  </profile>
</profiles>

Update:

My preferred way to use profiles is to have a default set of properties in my POM and then override these on demand using profiles in my settings file.

This approach is easy to do explicitly by using the "-s" and "-P" commandline parameters:

mvn -s $PROJECT_SETTINGS -P myProfile ....

This approach is easy to maintain in Jenkins using Config File Provider plugin which enables a GUI for editing the various settings files I use for each project.

Update 2:

Here's an example of how I setup my builds. The POM contains a section with the default property values. And I setup one or more pfiles to over-ride these values:

<project>
  <properties>
     <my.property1>hello</my.property1>
     <my.property2>world</my.property2>
     ..
  </properties>
  ..

  <build>
    <profiles>
      <profile>
        <id>build_in_spanish</id>
        <properties>
          <my.property1>hola</my.property1>
          <my.property2>mundo</my.property2>
          ..
        </properties>
      </profile>
      <profile>
        <id>build_in_irish</id>
        <properties>
          <my.property1>dia dhuit</my.property1>
          <my.property2>an domhain</my.property2>
          ..
        </properties>
      </profile>
    <profiles>
  </build>
</project>

So in this example the build defaults to English. To run the build with the settings in Spanish

mvn -P build_in_spanish ...

Note:

  • Profiles can be in the POM or in a separated settings file. The latter approach gives the most flexibility.
  • Profiles can be explicitly enabled (using the "-P" command line option or by attempting to discover the environment it sits within. This is a design choice)
Mark O'Connor
  • 76,015
  • 10
  • 139
  • 185
  • Why do I need the "activation" as you use the ${env.WAS##_HOME} directly. – Elyahu Aug 05 '13 at 08:41
  • Another question, what if the ENV variable is not SET or is Empty – Elyahu Aug 05 '13 at 08:42
  • Thanks Mark, but I still don't understand how do you traet case where the variable might not be set or set to nothing ? – Elyahu Aug 05 '13 at 14:11
  • @Elyahu Completely up to you. I've updated my answer with details on how I use profiles. – Mark O'Connor Aug 05 '13 at 14:12
  • Hi Mark, so ho do you treat cases where the variable is not set or empty ? – Elyahu Aug 06 '13 at 11:00
  • @Elyahu Updated with an example. I avoid empty value properties, by specifying defaults in the POM properties section. – Mark O'Connor Aug 06 '13 at 13:48
  • Thanks again Mark, your suggestion seems OK which I can use. But, I have to be backward compatible so if the property is defined as environment variable will it overwrite the definition in the pom.xml ? That pom.xml is the "parent pom" for all our developers so changing it can cause a big impact. – Elyahu Aug 11 '13 at 06:07
  • @Elyahu Instead of explicitly specifying the profile (like I do) why not trigger your profile using the environment variables? (See the profile activation documentation). That way you preserve backward compatibility, but gain the advantage of using profiles to manage your build environment. – Mark O'Connor Aug 11 '13 at 16:46
3

Apparently there is no way to do a proper IF-THEN-ELSE sentence in Maven. At least none that I found.

The closest thing I found was using the "activation" tag. which will activate the profile if the condition in it is met.

There is some bug on multiple conditions in Maven 2.0.X, not sure what's the status of it now -

http://jira.codehaus.org/browse/MNG-4565

So, a code example is answered on the question here -

Maven 2: Run maven-replacer-plugin with conditional replacement value?

But if you want to do something like << IF ... Then ... Else >> You're going to hit you head on a wall doing it. There are other ways, of course and I assume it is done in purpose, so you'll have to follow Maven way.

Thanks to all that tried to help Elyahu

Community
  • 1
  • 1
Elyahu
  • 226
  • 1
  • 2
  • 15
  • 2
    This is the big problem with Maven: *you have to do things the Maven way*, which is always so unintuitive that after two hours of trying to find and apply relevant documentation, I give up. – reinierpost Jan 27 '15 at 15:12
3

try to replace \> with /> in lines

<equals arg1="${env.WAS60_HOME}" arg2=""\>
1

usage of tasks inside properties tag is wired , use maven-antrun plugin instead. you can set maven properties with

http://maven.apache.org/plugins/maven-antrun-plugin/

<build>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<executions>
  <execution>
    <id>ftp</id>
    <phase>package</phase>
    <goals>
      <goal>run</goal>
    </goals>
    <configuration>
      <tasks>
        <taskdef resource="net/sf/antcontrib/antcontrib.properties"
          classpathref="maven.plugin.classpath" />
        <if>
          <equals arg1="${ftp}" arg2="true" />
          <then>
            <echo message="The value of property ftp is true" />
          </then>
          <else>
            <echo message="The value of property ftp is not true" />
          </else>
        </if>

      </tasks>
     <exportAntProperties>true</exportAntProperties>
    </configuration>
  </execution>
</executions>
<dependencies>
  <dependency>
    <groupId>ant-contrib</groupId>
    <artifactId>ant-contrib</artifactId>
    <version>20020829</version>
  </dependency>
</dependencies>
  </plugin>
</build>
mebada
  • 2,252
  • 4
  • 27
  • 35