Showing posts with label Gradle. Show all posts
Showing posts with label Gradle. Show all posts

2013-07-31

How to use Gradle to generate Eclipse files with relative paths to libraries

First, apply the Gradle Eclipse plug-in to your build.gradle file:

apply plugin: 'java'
apply plugin: 'eclipse'

You can now execute the following command to generate the Eclipse configuration files .project and .classpath:

$ gradle eclipse

You can now import and existing project into Eclipse, and enjoy all the correct configurations!

However, in the current Gradle version (1.6), the generated library paths are absolute, for example:

C:/Users/Miguel/.gradle/caches/artifacts-24/filestore/
junit/junit/4.11/source/
28e0ad201304e4a4abf999ca0570b7cffc352c3c/junit-4.11-sources.jar

This leads to problems because if you commit these files in source code control, your specific user settings will be imposed on other developers.

One way to avoid this is to use an Eclipse Classpath Variable and customize the Eclipse plug-in output.

eclipse {
    // find gradle cache location
    def gradleCache = null
    for (o in configurations.compile) {
        if (o.toString().indexOf(".gradle") != -1) {
            final def token = "filestore"
            def s = o.toString()
            def idx = s.indexOf(token)
            if (idx != -1) {
                gradleCache = new File(s.substring(0, idx + token.length()))
                break
            }
        }
    }
    assert gradleCache && gradleCache.exists()
    println "GRADLE_CACHE: " + gradleCache

    // replace absolute paths with classpath variable GRADLE_CACHE
    pathVariables 'GRADLE_CACHE': gradleCache

    // make sure GRADLE_CACHE is defined in 
    // Eclipse, Preferences, Java, Build Path, Classpath Variables

}

Note: an alternative solution could use Eclipse workspace Path variables (referred using the ${...} notation) but without DSL support like the pathVariables statement above.

2012-08-09

Gradle introspection

I've been using the Gradle build tool for a while now, and it has been a very good experience. Not so much with Groovy beyond scripts, but that is another story... :)

Today I had a dependency problem caused by two alternative libraries being loaded at the same time (see SLF4J Multiple Binding).

To diagnose the problem I used the following Gradle inspection commands:
gradle dependencies

gradle properties

gradle tasks
(see user guide, chapter 11)

Here the excerpt from the dependencies command:
------------------------------------------------------------
Project :Util
------------------------------------------------------------

compile - Classpath for compiling the main sources.
+--- junit:junit:4.10 [default]
|    \--- org.hamcrest:hamcrest-core:1.1 [compile,master,runtime]
+--- org.apache.jena:jena-core:2.7.2 [default]
|    +--- org.apache.jena:jena-iri:0.9.2 [compile,master,runtime]
|    |    +--- org.slf4j:slf4j-api:1.6.4 [compile,master,runtime]
|    |    +--- org.slf4j:slf4j-log4j12:1.6.4 [compile,master,runtime]
|    |    |    +--- org.slf4j:slf4j-api:1.6.4 [compile,master,runtime] (*)
|    |    |    \--- log4j:log4j:1.2.16 [compile,master,runtime]
|    |    \--- log4j:log4j:1.2.16 [compile,master,runtime] (*)
|    +--- xerces:xercesImpl:2.10.0 [compile,master,runtime]
|    |    \--- xml-apis:xml-apis:1.4.01 [compile,master,runtime]
|    +--- org.slf4j:slf4j-api:1.6.4 [compile,master,runtime] (*)
|    +--- org.slf4j:slf4j-log4j12:1.6.4 [compile,master,runtime] (*)
|    \--- log4j:log4j:1.2.16 [compile,master,runtime] (*)
\--- javax.mail:mail:1.4.5 [default]
     \--- javax.activation:activation:1.1 [compile,master,runtime]

...
(*) - dependencies omitted (listed previously)

To exclude the log4j binding dependency, I added the following to build.gradle:
configurations {
    all*.exclude(group: 'org.slf4j', module: 'slf4j-log4j12')
    all*.exclude(group: 'log4j', module: 'log4j')
}
(see user guide 43.4.7. Excluding transitive dependencies
)

The new dependency tree now excludes the troublesome dependency:
compile - Classpath for compiling the main sources.
+--- org.apache.jena:jena-core:2.7.2 [default]
|    +--- org.apache.jena:jena-iri:0.9.2 [compile,master,runtime]
|    |    \--- org.slf4j:slf4j-api:1.6.4 [compile,master,runtime]
|    +--- xerces:xercesImpl:2.10.0 [compile,master,runtime]
|    |    \--- xml-apis:xml-apis:1.4.01 [compile,master,runtime]
|    \--- org.slf4j:slf4j-api:1.6.4 [compile,master,runtime] (*)
\--- javax.mail:mail:1.4.5 [default]
     \--- javax.activation:activation:1.1 [compile,master,runtime]

...

2011-11-03

Tackling a test in an infinite loop

I had a bug that was causing a unit test to go in an infinite loop. Gradle would not print any output from the test because the standard output stream is captured to a test report.

To debug I used the following two techniques:

1 - I accessed the actual standard output, bypassing Gradle's redirection for this specific situation (this is usually not a good idea):

    PrintStream actualStdout = new PrintStream(
        new FileOutputStream(FileDescriptor.out))
    actualStdout.println("test message")

2 - I placed a pause inside the loop that was not stopping to be able to read the messages and make sense of them in human timescale (1000 milliseconds = 1 second).

    Thread.sleep(1000)
 

Gradle flatDir repository

Q:
"
For a Gradle flatDir repository, is it looking for a local filesystem that is built up like Maven (pom's etc)..
or is it just looking for jar files in a folder called lib?
"

repositories {
flatDir name: 'localRepository', dirs: 'lib'
}


A:
"
As you assume it just looks for jars/wars/whatever in the 'lib' folder. It resolves versions by looking at the version number in the filename. for instance:
myveryownjar-1.2.0.jar
spring-2.5.6.jar
"

"
Pretty much. For each dependency that you declare in the build script, Gradle will look for a corresponding file in the 'lib' directory. For example, for a dependency on 'junit:junit:4.7', Gradle would look for
lib/junit-4.7.jar or lib/junit.jar. It assumes there are no transitive dependencies.
"

Adapted from http://gradle.1045684.n5.nabble.com/Flat-Dir-repositories-td1431519.html

Groovy and Gradle

The next generation of Java and Ant (+Maven): Groovy and Gradle.



There are still some improvements required but these tools represent major steps forward in programmer productivity.