Search code examples
javaantant-contrib

apache ant mutable file type property


I'm looking for a way to load properties from a file in ant script. Specifically, I want to loop through a list of properties files, and on each loop load the properties from the current file and do something with it. Something like this:

<for param="file">
  <path>
    <fileset containing my properties files.../>
  </path>
  <sequential>
     <property file="@{file}" prefix="fromFile"/>
     <echo message="current file: @{file}"/>
     <echo message="property1 from file: ${fromFile.property1}"/>
  </sequential>
</for>

The code above results in only the first properties file from being read, even though each loop does go through each properties file name. I know property is immutable, and I can get around it by using local task or variable task from ant-contrib. However, I don't know how to apply them here, or if they even contribute to a solution in this case.


Solution

  • Here I used Antcontrib and two property files in the same directory as the build.xml.

    p1.properties:

    property1=from p1
    

    p2.properties:

    property1=from p2
    

    The trick is to use antcall inside the for loop to call another target. Properties set in the called target at not propagated back to the caller.

    build.xml:

    <project name="test" default="read.property.files">
      <taskdef resource="net/sf/antcontrib/antcontrib.properties">
        <classpath>
          <pathelement location="ant-contrib/ant-contrib-1.0b3.jar"/>
        </classpath>
      </taskdef>
    
      <target name="read.property.files">
        <for param="file">
          <path>
            <fileset dir="." includes="*.properties"/>
          </path>
          <sequential>
            <antcall target="read.one.property.file">
              <param name="propfile" value="@{file}"/>
            </antcall>
          </sequential>
        </for>
      </target>
    
      <target name="read.one.property.file">
        <property file="${propfile}" />
        <echo message="current file: ${propfile}" />
        <echo message="property1 from file: ${property1}"/>
      </target>
    </project>
    

    The output is:

    Buildfile: /home/vanje/anttest/build.xml
    
    read.property.files:
    
    read.one.property.file:
         [echo] current file: /home/vanje/anttest/p1.properties
         [echo] property1 from file: from p1
    
    read.one.property.file:
         [echo] current file: /home/vanje/anttest/p2.properties
         [echo] property1 from file: from p2
    
    BUILD SUCCESSFUL
    Total time: 0 seconds