One of the great features of Gradle is incremental build support. With incremental build support a task is only executed if it is really necessary. For example if a task generates files and the files have not changed than Gradle can skip the task. This speeds up the build process, which is good. If we write our own tasks we can use annotations for properties and methods to make them behave correctly for incremental build support. The @OutputDirectory
annotation for example can be used for a property or method that defines a directory that is used by the task to put files in. The nice thing is that once we have designated such a directory as the output directory we don't have to write code to create the directory if it doesn't exist. Gradle will automatically create the directory if it doesn't exist yet. If we use the @OutputFile
or @OutputFiles
annotation the directory part of the file name is created if it doesn't exist.
In the following example build file we create a new task SplitXmlTask with the property destinationDir
and we apply the @OutputDirectory
annotation. If the directory doesn't exist Gradle will create it when we execute the task.
Continue reading →
Gradle is very flexible. One of the ways to alter the build configuration is with initialization or init scripts. These are like other Gradle scripts but are executed before the build. We can use different ways to add the init script to a build. For example we can use the command-line option -I
or --init-script
, place the script in the init.d
directory of our GRADLE_HOME
directory or USER_HOME/.gradle
directory or place a file init.gradle
in our USER_HOME/.gradle
directory.
We can also use the apply(from:)
method to include such a script in our build file. We can reference a file location, but also a URL. Imagine we place an init script on our company intranet to be shared by all developers, then we can include the script with the apply(from:)
method. In the following build file we use this syntax to include the script:
Continue reading →
We can exclude transitive dependencies easily from specific configurations. To exclude them from all configurations we can use Groovy's spread-dot operator and invoke the exclude()
method on each configuration. We can only define the group, module or both as arguments for the exclude()
method.
The following part of a build file shows how we can exclude a dependency from all configurations:
Continue reading →
With Gradle we can execute Java applications using the JavaExec
task or the javaexec()
method. If we want to run Java code from an external dependency we must first pull in the dependency with the Java application code. The best way to do this is to create a new dependency configuration. When we configure a task with type JavaExec
we can set the classpath to the external dependency. Notice we cannot use the buildscript{}
script block to set the classpath. A JavaExec
task will fork a new Java process so any classpath settings via buildscript{}
are ignored.
In the following example build script we want to execute the Java class org.apache.cxf.tools.wsdlto.WSDLToJava
from Apache CXF to generate Java classes from a given WSDL. We define a new dependency configuration with the name cxf
and use it to assign the CXF dependencies to it. We use the classpath
property of the JavaExec
task to assign the configuration dependency.
Continue reading →
We can introduce Groovy into our Java projects at grassroots level. Even if we aren't allowed to run the Groovy compiler we can use other ways to run Groovy code. As long as we can include the Groovy libraries as a compile dependency than we can already use Groovy from Java. In this post we see how we can use the power of XmlSlurper
to parse XML from our Java code.
To execute a Groovy script from we can use a GroovyShell
object and invoke the evaluate()
method. The evaluate()
method can parse a Groovy script as File
or Reader
object. We can also use a String
value to be evaluated. The last statement of the script that is evaluated can be assigned to a Java variable. To pass variables to the script we use the Binding
object. This is a map of variables and their values. We assign values to the variables in the Java code and in the Groovy script we can use the variable values.
Continue reading →
Since Groovy 1.8.7 we can create a list and use the withDefault()
method to define a default value for elements that are not yet in the list. We use a closure as argument of the method, which returns the default value. We can even access the index of the element in the closure as an argument.
Besides the withDefault()
method we can use the withLazyDefault()
which is just another name for the same functionality. If we request a value for an index that is greater or equal to the size of the list, the list will automatically grow up to the specified index. Any gaps are filled with the value null
.
Continue reading →
Since Groovy 1.8.7 we can use the first()
and last()
methods on Iterable
objects. With the first()
method we get the first element and with the last()
method we get the last element:
def list = 0..100
assert list.first() == 0
assert list.last() == 100
def abc = 'abc' as Character[]
assert abc.first() == 'a'
assert abc.last() == 'c'
def s = ['Groovy', 'Gradle', 'Grails', 'Rocks'] as Set
assert s.first() == 'Groovy'
assert s.last() == 'Rocks'
Continue reading →
Git supports hooks, which are scripts that are fired when certain events happens. The scripts are simply shell scripts and we can use Groovy to run those scripts. We must make Groovy the script language with the hash-bang (#!
) header in the Git hook script file. And then we are ready to go and use Groovy as the script language for the Git hooks.
Git hooks are placed in the .git/hooks
directory of our project. We create an example script that will use growlnotify
to create a notification message with information from the Git commit action. growlnotify
is a command-line tool for Mac OSX to send out messages to Growl. Other operating systems also have tools to create notification message from the command-line.
Continue reading →
We can use the Gradle announce
plugin to send announcements from the build process. We can send data to Twitter (I don't know if our followers are waiting for this, but if you want to you can), but also to notification applications on our local computers. For Mac OSX Growl is supported, for Linux notify-send and for Windows Snarl.
The plugin adds an announce
object with the announce()
method. The method accepts two arguments. The first argument is the message and the second argument is either twitter
or local
to indicate where to send the announcement.
Continue reading →
Groovy closures are powerful. A closure can be passed to methods as argument or defined as a variable. We can even return closures from methods or other closures. We can use the returned closure to execute the logic from the closure with the explicit call()
method or the implicit syntax with just the closure object followed by opening and closing parentheses (()
).
// Method returns a closure. Method could
// also have been another closure to return
// the closure.
def repeater(times) {
{ value -> value * times }
}
// Use explicit call() method on the return closure
// object from the repeater() method.
assert repeater(2).call('mrhaki') == 'mrhakimrhaki'
// Use implicit call() method on the return closure
// object from the repeater() method. This
// might looks strange at first...
assert repeater(2)('mrhaki') == 'mrhakimrhaki'
Continue reading →
Since Groovy 2 we can use a subset of the Project Coin features from Java 7. But we don't have to run Java 7 to use them in Groovy code. We can use the new features even if we run our Groovy code on older Java versions.
Groovy didn't have to add all Project Coin features, because some are already supported in Groovy, like the switch
statement on String
objects or diamond operator. A feature that is added is a syntax enhancement to define binary literals. We can now use binary integral literals by prefixing the value with 0b
:
Continue reading →
In Groovy we can use the drop()
and take()
methods to get elements from a collection or String
object. Since Groovy 1.8.7 we also can use the dropWhile()
and takeWhile()
methods and use a closure to define a condition to stop dropping or taking elements. With the dropWhile()
method we drop elements or characters until the condition in the closure is true
. And the takeWhile()
method returns elements from a collection or characters from a String
until the condition of the closure is true
. In the following example we see how we can use the methods:
def s = "Groovy Rocks!"
assert s.takeWhile { it != 'R' } == 'Groovy '
assert s.dropWhile { it != 'R' } == 'Rocks!'
def list = 0..10
assert 0..4 == list.takeWhile { it < 5 }
assert 5..10 == list.dropWhile { it < 5 }
def m = [name: 'mrhaki', loves: 'Groovy', worksAt: 'JDriven']
assert [name: 'mrhaki'] == m.takeWhile { key, value -> key.length() == 4 }
assert [loves: 'Groovy', worksAt: 'JDriven'] == m.dropWhile { it.key == 'name' }
Continue reading →