Monday, June 30, 2014

Apache Ant vs Gradle : Properties

Here's how to define a property in Apache Ant:
<property name = "msg" value = "Hello World" />
Then to use the property you use the ${name} syntax.
<echo message = "msg = ${msg}" />
Since build scripts in Gradle are really just Groovy code, Gradle supports both variables and properties.  So what's the difference between the two?  Well for starters you can specify a type for variables.
String msg = "Hello World"
Properties, on the other hand, must remain untyped.  Specifying a type for a property causes Gradle to think that that property's name is the same as its type.  For example, the following code causes Gradle to think the build script has a property named String.
ext {
   String msg = "Hello World" // error
}
Another difference is their scope. Unfortunately scope is a complicated topic in Gradle, but just to show that there is a difference between the two let's look at an example build script.
// local variable named msg
String msg = "Hello World"

copy {
   from "oldGradle.txt"
   into "."
   rename "oldGradle.txt", "newGradle.txt"

   println "(copy) msg = ${msg}"
}

println "msg = ${msg}"

def speak( ) {
   // println "(speak) msg = ${msg}" // error
}

speak( );
Notice that the msg variable cannot be accessed inside the method speak( ).  If msg had been defined as a property, however, then we could access it.
// String msg = "Hello World"

ext {
   // project property named msg
   msg = "Hello World"
}

copy {
   from "oldGradle.txt"
   into "."
   rename "oldGradle.txt", "newGradle.txt"

   println "(copy) msg = ${msg}"
}

println "msg = ${msg}"

def speak( ) {
   println "(speak) msg = ${msg}" // ok
}

speak( );
Properties in Apache Ant are immutable.  Once set, they cannot be changed.
<property name = "msg" value = "good morning" />
<!-- 
   // This causes an errror
   <property name = "msg" value = "bonjour" />  
-->
<echo message = "msg = ${msg}" />
Properties in Gradle, however, can be changed.
ext {
   msg = "good morning"
}

msg = "bonjour"

println "msg = ${msg}"  // outputs: bonjour
If you want to move your property definitions into a separate file, in Apache Ant you use the property element's file attribute.
# build.properties
msg = Hello World
<!-- build.xml -->
<?xml version="1.0"?>
<project>
 <property file = "build.properties" />
 <echo message = "msg = ${msg}" />
</project>
Gradle expects properties to be defined in a file called gradle.properties:
# gradle.properties
msg = Hello World
// build.gradle
println "msg = ${msg}"
Note: I tried importing properties using a ResourceBundle but got the following error message:
C:\newFolder>gradle

FAILURE: Build failed with an exception.

* Where:
Build file 'C:\newFolder\build.gradle' line
: 6

* What went wrong:
A problem occurred evaluating root project 'newFolder'.
> Can't find bundle for base name build, locale en_US

* Try:
Run with --stacktrace option to get the stack trace.
Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 3.447 secs
Here's the code that I used.
import java.util.ResourceBundle

ResourceBundle.getBundle("build")
From the looks of this Gradle forum topic, there is a way to do this. I just don't know how. I was able to read the resource bundle using Groovy (no Gradle).

References

 

No comments:

Post a Comment