Bookmark and Share

Spring Framework guides ''Building Java Projects with Gradle'': http://spring.io/guides/gs/gradle/ is a good reference for this topic.

Install Gradle

On macOS, install with Homebrew

$ brew install gradle
==> Downloading https://services.gradle.org/distributions/gradle-1.12-bin.zip
######################################################################## 100.0%
    /usr/local/Cellar/gradle/1.12: 155 files, 44M, built in 106 seconds$ brew install gradle
==> Downloading https://services.gradle.org/distributions/gradle-1.12-bin.zip
######################################################################## 100.0%
    /usr/local/Cellar/gradle/1.12: 155 files, 44M, built in 106 seconds

Verify it's installed successfully:

$ which gradle
/usr/local/bin/gradle
$ gradle -version

------------------------------------------------------------
Gradle 2.0
------------------------------------------------------------

Build time:   2014-07-01 07:45:34 UTC
Build number: none
Revision:     b6ead6fa452dfdadec484059191eb641d817226c

Groovy:       2.3.3
Ant:          Apache Ant(TM) version 1.9.3 compiled on December 23 2013
JVM:          1.6.0_65 (Apple Inc. 20.65-b04-462)
OS:           macOS 10.9.4 x86_64

Create Gradle-managed Java projects in IntelliJ IDEA

Really, there are just two easy steps:

Create New Project, and then

☝ step 1: pick Gradle, check "Use auto-import", check "Create directories for empty content roots automaticaly", pick JDK version,

☝ step 2: specify settings of the project.

Alternatively, one can create a Java project using Gradle from UNIX command line and optionally import it later into an IDE such as IntelliJ IDEA or Eclipse.

Create a Java project using Gradle

Create a project using Gradle:

$ mkdir gradlehelloworld
$ cd gradlehelloworld
$ gradle init --type java-library
:wrapper
:init

BUILD SUCCESSFUL

Total time: 4.974 secs

Alternatively, use gradle buildInit --type java-library to create it.

It automatically creates the project structure including directories and template files:

$ tree
.
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
    ├── main
    │   └── java
    │       └── Library.java
    └── test
        └── java
            └── LibraryTest.java

7 directories, 8 files

Make a minimal and slightly non-trivial Java program including tests and Gradle build script

I'll rename Library to Main in the file names and source code, and create a toy Java project with a test:

Main.java:

package gradlehelloworld;

import com.google.common.base.Strings;

public class Main {
    public static void main(String[] args) {
        System.out.println(getGreeting("World"));
        System.out.println("My name is " + System.getProperty("gradlehelloworld.name"));
    }

    static String getGreeting(String name) {
        return Strings.repeat(String.format("Hello %s!\n", name), 2);
    }
}

MainTest.java:

package gradlehelloworld;    

import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import org.junit.Test;

public class MainTest {
    @Test
    public void getGreeting() {
        Main classUnderTest = new Main();
        assertThat(classUnderTest.getGreeting("World"),
                   equalTo("Hello World!\nHello World!\n"));
    }
}

Edit the Gradle build script gradlehelloworld/build.gradle:

// Apply the java plugin to add support for Java
apply plugin: 'java'
apply plugin: 'application'

sourceCompatibility = '1.6'

mainClassName = 'gradlehelloworld.Main'

// In this section you declare where to find the dependencies of your project
repositories {
    // Use 'maven central' for resolving your dependencies.
    // You can declare any Maven/Ivy/file repository here.
    mavenCentral()
}

// In this section you declare the dependencies for your production and test code
dependencies {
    // The production code uses the SLF4J logging API at compile time
    // compile 'org.slf4j:slf4j-api:1.7.5'
    compile 'com.google.guava:guava:17.0'

    // Declare the dependency for your favourite test framework you want to use in your tests.
    testCompile 'junit:junit:4.11'
}

run {
    systemProperty 'gradlehelloworld.name', 'FooBar'
}

I added these code in a repository on GitHub. The actual code in the repository is slightly different from the above as I have developed new content and played with variations in it.

Run/build Java project using Gradle

Let Gradle download dependency Guava from Maven Central repository, compile Main.java program, set gradlehelloworld.name to "FooBar", and run it with Guava on the Java classpath:

$ gradle run
:compileJava
Download http://repo1.maven.org/maven2/com/google/guava/guava/17.0/guava-17.0.pom
Download http://repo1.maven.org/maven2/com/google/guava/guava-parent/17.0/guava-parent-17.0.pom
Download http://repo1.maven.org/maven2/com/google/guava/guava/17.0/guava-17.0.jar
:compileJava FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':compileJava'.
> invalid source release: 1.8

* 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: 14.309 secs

If I change

sourceCompatibility = '1.8'

to

sourceCompatibility = '1.6'

it then works:

$ gradle run
:compileJava
:processResources UP-TO-DATE
:classes
:run
Hello World!
Hello World!

My name is FooBar

BUILD SUCCESSFUL

Total time: 6.13 secs

To use sourceCompatibility = '1.8', it might need to set JAVA_HOME environment variable to value of /usr/libexec/java_home -v 1.8.

Do a full build including running tests:

$ gradle build
:compileJava
:processResources UP-TO-DATE
:classes
:jar UP-TO-DATE
:assemble UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build UP-TO-DATE

BUILD SUCCESSFUL

Total time: 6.489 secs

Check the test report at

./build/reports/tests/index.html

Remarks:

  • Note it uses assertThat instead of assertTrue

assertTrue(classUnderTest.getGreeting("World"), equalTo("Hello World!\nHello World!\n"));

assertThat(classUnderTest.getGreeting("World"), equalTo("Hello World!\nHello World!\n"));

At this point your project structure looks like:

$ tree
.
├── build
│   ├── classes
│   │   ├── main
│   │   │   ├── gradle_hello_world
│   │   │   │   └── Main.class
│   │   │   └── gradlehelloworld
│   │   │       └── Main.class
│   │   └── test
│   │       └── gradlehelloworld
│   │           └── MainTest.class
│   ├── dependency-cache
│   ├── libs
│   │   ├── gradle_hello_world.jar
│   │   └── gradlehelloworld.jar
│   ├── reports
│   │   └── tests
│   │       ├── classes
│   │       │   ├── css
│   │       │   │   ├── base-style.css
│   │       │   │   └── style.css
│   │       │   ├── gradlehelloworld.MainTest.html
│   │       │   ├── htc
│   │       │   │   └── css3-pie-1.0beta3.htc
│   │       │   └── js
│   │       │       └── report.js
│   │       ├── css
│   │       │   ├── base-style.css
│   │       │   └── style.css
│   │       ├── htc
│   │       │   └── css3-pie-1.0beta3.htc
│   │       ├── index.html
│   │       ├── js
│   │       │   └── report.js
│   │       └── packages
│   │           ├── css
│   │           │   ├── base-style.css
│   │           │   └── style.css
│   │           ├── gradlehelloworld.html
│   │           ├── htc
│   │           │   └── css3-pie-1.0beta3.htc
│   │           └── js
│   │               └── report.js
│   ├── test-results
│   │   ├── TEST-gradlehelloworld.MainTest.xml
│   │   └── binary
│   │       └── test
│   │           ├── output.bin
│   │           ├── output.bin.idx
│   │           └── results.bin
│   └── tmp
│       └── jar
│           └── MANIFEST.MF
├── build.gradle
├── build.gradle~
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
├── settings.gradle~
└── src
    ├── main
    │   └── java
    │       ├── Main.java
    │       └── Main.java~
    └── test
        └── java
            ├── MainTest.java
            └── MainTest.java~

34 directories, 37 files

The build/ sub-directory contains the build, Java doc pages, JUnit test reports, etc.

Import the project into IntelliJ IDEA

IntelliJ IDEA is a popular IDE for Java. One can import the Gradle project created above to the IDE.

  1. Import the Gradle project into IntelliJ IDEA, by following the documentation instruction "Importing Project from Gradle Model". For project settings, I just chose "Use default gradle wrapper (recommended)", which seems to cause a predefined set of tasks to be created in the Gradle tool window such as "compile", "build", "clean", etc.
  2. It turns out that the depended packages need to be separately specified in IntelliJ IDEA in addition to build.gradle. Namely, download the com.google.guava library by following the instruction in documentation -- I picked com.google.guava:guava:17 (format is package:artifact:version) to download. (Warning: in IntelliJ IDEA 13.1, I found that one sometimes need to hit the magnifier icon multiple times for it to find a specific artifact from Maven. So don't get confused if it does not find it the first time.)
  3. Add the library as a "project library" (by following the automatically prompted window after step 2) or as a global library, by following the documentation instruction "Configuring Project and Global Libraries".
  4. Specify that your Java module depends on the com.google.guava package, following the documentation instruction "Configuring Module Dependencies and Libraries";
  5. If the IDE still reports "Cannot resolve symbol 'google'" and highlights 'google' as red in import com.google.common.base.Strings, one may try using File | Invalidate Caches / Restart … to force the rebuilding of syntax highlighting in the editor window.
  6. One can then open the Gradle tool window, and run the various Gradle tasks such as "compile", "build", and "clean".

Run Gradle tasks from IntelliJ IDEA Gradle Tool Window

The official IntelliJ IDEA documentation ''Gradle Tool Window'' to get an introduction. Hitting build under "All tasks" is equivalent to running gradle build at UNIX command line. It generates /build under project root path. Note JUnit test report is at /build/reports/tests/; Similarly, compileJava compiles Java and javadoc creates Javadoc pages in /build/javadoc/. See Gradle documentation for the list of Gradle tasks.

References

blog comments powered by Disqus