Gradle

Gradle Goodness: Distribute Custom Gradle in Our Company

Posted on by  
Hubert Klein Ikkink

The Gradle wrapper allows us to let developers use Gradle without the need for every developer to install Gradle. We can add the output of the Gradle wrapper task to version control. Developers only need to checkout the source for a project and invoke the gradlew or gradlew.bat scripts. The scripts will look for a Gradle distribution and download it to the local computer of a developer. We can customize the Gradle wrapper and provide a different source for the Gradle distribution. For example we can add the Gradle distribution ZIP file on our company intranet. We then use the distributionUrl property of the Wrapper task to reference the intranet location where we place the Gradle distribution ZIP file.

In the following sample file we use the distributionUrl property to reference our company intranet:

Continue reading →

Gradle Goodness: Task Output Annotations Create Directory Automatically

Posted on by  
Hubert Klein Ikkink

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 Goodness: Init Script for Adding Extra Plugins to Existing Projects

Posted on by  
Hubert Klein Ikkink

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 →

Gradle Goodness: Exclude Transitive Dependency from All Configurations

Posted on by  
Hubert Klein Ikkink

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 →

Gradle Goodness: Running Java Applications from External Dependency

Posted on by  
Hubert Klein Ikkink

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 →

Gradle Goodness: Getting Announcements from Gradle Build

Posted on by  
Hubert Klein Ikkink

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 →

Gradle Goodness: Customize IDEA Project File Generation

Posted on by  
Hubert Klein Ikkink

With the Gradle IDEA plugin we can generate JetBrains IntelliJ IDEA project files. The plugin uses defaults from our project to generate the files. If we also apply the Java plugin to our project then the Java settings for the project files are generated. We can customize the file generation in several ways. The most low level method is using the withXml hook. With this hook we have access to the XML before the file is written to disk. Here we can add or change XML elements and attribute values. We use a closure as argument for the withXml hook and Gradle adds a XmlProvider object as argument. The easiest way to manipulate the XML is getting a groovy.util.Node from the XmlProvider. We also can get a DOM Element or StringBuilder to work with. In the following example build file we change the contents of the IDEA project file (with extension .ipr). We change the output directory of the JavaDoc tool. We use Groovy syntax to find the JavadocGenerationManager which is automatically added, because we have the Java plugin in our build file. We also change the Encoding component or create it when it doesn't exist:

apply plugin: 'java'
apply plugin: 'idea'

idea {
    project {
        // Here we customize the .ipr file generation.
        ipr {
            // XML hook to customize the XML before
            // it is written to disk
            withXml { xmlProvider ->
                // Get root node.
                def project = xmlProvider.asNode()

                customizeJavaDoc project
                customizeEncoding project
            }
        }
    }
}

/* Customize JavadocGenerationManger component */
def customizeJavaDoc(project) {
    def javaDocGenerationManager = findComponent(project, 'JavadocGenerationManager')
    changeOption javaDocGenerationManager, 'OUTPUT_DIRECTORY', '$PROJECT_DIR$/out/javadoc'
}

/* Search component with given name */
def findComponent(project, name) {
    project.component.find { it.@name == name }
}

/* Set value for option node with given name */
def changeOption(node, name, value) {
    node.option.find { it.@name == name }.@value = value
}

/* Customize Encoding component */
def customizeEncoding(project) {
    def encoding = findComponent(project, 'Encoding')

    if (encoding) {
        // Change existing node.
        encoding.@useUTFGuessing = true
        encoding.@native2AsciiForPropertiesFiles = true
        encoding.@defaultCharsetForPropertiesFiles = 'UTF-8'
    } else {
        // Create new node with default values.
        project.appendNode 'Encoding', [useUTFGuessing: true, native2AsciiForPropertiesFiles: true, defaultCharsetForPropertiesFiles: 'UTF-8']
    }
}

Continue reading →

Gradle Goodness: Using Objects for Version

Posted on by  
Hubert Klein Ikkink

One of the great things of Gradle is that the build scripts are code. We can use all the features of the Groovy language, we can refactor our build scripts to make them more maintainable, we can use variables and properties to define values and much more, just like our application code. In this post we see how we can create a class to define a version in our build script. To set the version of a Gradle project we only have to assign a value to the version property. Normally we use a String value, but we can also assign an object. Gradle will use the toString() method of the object to get the String value for a version. In the following build script we define a new class Version in our build script. We create an instance of the class and assign it to the version property. With the task printVersion we can see the value of the version property:

version = new Version(major: 2, minor: 1, revision: 14)

task printVersion {
    doFirst {
        println "Project version is $version"
    }
}

defaultTasks 'printVersion'

class Version {
    int major, minor, revision

    String toString() {
        "$major.$minor.$revision"
    }
}

Continue reading →

shadow-left