using checkstyle in gradle

The checkstyle plugin brings code quality checks into the gradle build. This way, if team members are using disparate IDEs or have different settings, consistent coding standards are enforced in the build.

Here’s how to add checkstyle to your Java build in two steps:
1) In build.gradle, add this:

    apply plugin: ‘checkstyle’


    checkstyle {
       configFile = new File(rootDir, “checkstyle.xml“)
    }

The configFile setting is not necessary if you use the default location, which is config/checkstyle/checkstyle.xml. More configuration options are listed in the gradle userguide.


If yours is a multiproject build, put that configuration in a subprojects block in the parent build.gradle. This uses the parent’s rootDir/checkstyle.xml so the checkstyle configuration is consistent between projects.

2) Create checkstyle.xml. For reasonable default settings, google it and steal someone else’s. I took mine from a google-api repo and stripped it down. Here’s a really basic example, which checks only for tab characters and unused imports:


<!DOCTYPE module PUBLIC
    “-//Puppy Crawl//DTD Check Configuration 1.3//EN”
     “http://www.puppycrawl.com/dtds/configuration_1_3.dtd”&gt;


 
   
 

Visit the checkstyle site to find a million more options for checks.

Connecting Java Projects in Gradle

The problem: multiple Java projects, each with their own Gradle build, dependent on each other but not linked.
The goal: connect them into one great build to rule them all.
The caveat: without messing with the individual builds. It is 3 days before go-live at this startup.

The solution:
1) get all of the projects under one subdirectory. They don’t have to be immediate subdirectories, just somewhere under one directory to rule them all. Note that soft links won’t work, because the subprojects need to see up to the rule-them-all.
2) in that directory to rule them all, create settings.gradle to list the projects

import ‘picture’, ‘tools:hammer’, ‘tools:hanger’

Note the colon delimiter for subdirectories.

3) in the directory to rule them all, create build.gradle to set up the dependencies.


project(‘:picture’) {
  dependencies {
    compile project(‘:tools:hammer’), project(‘:tools:hanger’)
  }
}


this is all that’s needed to define the dependencies… except that it doesn’t quite work. The error is:


> No signature of method: org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.compile() is applicable for argument types: (org.gradle.api.internal.project.DefaultProject_Decorated, org.gradle.api.internal.project.DefaultProject_Decorated) values: [project ‘:tools:hammer’, project ‘:tools:hanger’]

Before that ‘compile’ concept exists, we have to apply the Java plugin to each subdirectory. Even though each local build.gradle applies the plugin, we need it earlier than that, at the top level.

4) Put this at the top of the new build.gradle file:
subprojects {
  apply plugin: ‘java’
}

Once the dependencies are defined here, builds of individual projects will trigger builds of their dependencies. The output of each dependency will automatically be added to the classpath of the dependent project. It’s pretty sweet: whether you perform the build from the rule-them-all directory or from the subproject you’re currently working on, Gradle looks upward in the directory structure, learn about dependencies, and build other subprojects as necessary.

Anecdote:
On the path from the cryptic error message, I consulted the one true documentation (the source code).
The example in the documentation ran, but not my build. My build gave that “No signature of method” error. To learn what was going on inside the dependencies block, I printed info about the delegate objects (see this post); the delegate objects were the same. No compile method existed on either of them. Where to look next? How is it finding the compile method in the example that runs?
This is where just a little knowledge of Ruby comes in. I spotted a method in the delegate object called methodMissing. In Ruby, creating this method lets the object decide what to do with any method call not already defined. It turns out that Groovy works the same way. This was the right place to put the debug point in IntelliJ IDEA.
Comparing the behavior of methodMissing showed that the compile configuration existed in the example but not in my build. That led to “oh, maybe we need to apply the Java plugin first.”

The multiproject build is working beautifully now, with 0 modifications to the subprojects. Happy birthday, Gradle 1.0!

IntelliJ IDEA 11

The new version of IntelliJ IDEA is out, and I’m liking it.

Gradle integration: creating a new project from a build.gradle was smooth and easy. Then when dependencies were added to the gradle file, the gradle plugin came in handy. One line added to build.gradle

apply plugin: 'idea'

and then one execution of

gradle idea

updated the dependencies without losing my other settings.

Git integration: it’s built-in, but I haven’t tried it yet. I’m still making friends with git at the command line. in the meantime, I added .idea, *.ipr and *.iws to the .gitignore list.

Android integration: this is smooth. It was a little rough in the last version. In 11, it’s slick so far. Clicking on an R.id.viewName takes me directly to the definition of that layout element in the XML. The IDE also has a GUI editor for creating layouts — priceless. (I do have an issue with the resources not being regenerated and packaged correctly on changes to layouts. I haven’t yet narrowed it down closely enough to report a bug. Rebuilding the project fixes it.)

Final variables: Type an expression, then press ctrl-alt-v for “create a local variable to store the results of this expression.” A little thought bubble appears containing a checkbox for “Declare final.” Having checked that once, my created variables are now final by default. Hurray!

JetBrains supports the local user group community by giving free licenses to attendees (one random giveaway at each meeting of the St. Louis JUG when at least thirty people show up, which is most of the time). JetBrains also supplies licenses to leaders of the JUG. This is a great reason to be active in the local user group community!

Gradle is easy: Groovy tests

Today in Unit Testing, an evil framework class hid my important return value away in a private field.

Groovy to the rescue!

So far, all our code and tests are in Java. It took only two lines in build.gradle, as specified in the gradle documentation, and poof.

I put my little test class in src/test/groovy/package/structure, typed “gradle build” and wa-la! The results from the groovy test show up right along with the Java tests. Sweet.


class SomethingTest {
def email = "blah@blha.com";

UsefulClass usefulClass
CheckEmail subject

@Before
void setup() {
usefulClass = mock(UsefulClass.class);
subject = new Something(userService);
subject.setEmailAddress(email);
}

@Test
void falseWhenEmailFound() {
when(usefulClass.find(email)).thenReturn(new Thingie());

Reply result = subject.methodUnderTest();

assertEquals result.entity , Boolean.FALSE // see? that mean old private field is right there for the testing.
}

Stupid Gradle Tricks #1: what can I do in this block?

In the previous post, we saw that each labeled block in a Gradle build file is really a closure with DELEGATE_FIRST scope. Each of these blocks has access to all the methods on the delegate object. The class of that delegate object varies by block.

Even looking at the source code to identify the class of the delegate won’t tell you every method that’s available on it. This is because Gradle plugins dynamically add methods to these things.

Here is a sneaky trick to find out what’s available to you in a particular block. If you give the closure one argument, Gradle will populate it with the delegate. Then you can have the build print out information about it.

The following build script prints out the class of the repositories delegate and every method that’s on it, formatting the output to remove bulky package information.


apply plugin: 'java'

def printDelegateInfo (String blockName, Object d) {
println "---- ${blockName} block ----"
println "Delegate is of class " + d.class
d.class.methods.each {
println (("Method: " + it + " from " + it.declaringClass =~ /[a-zA-Z\.]*\./).replaceAll("") )
}
println "----------------------------"
}

repositories { d ->
printDelegateInfo("repositories", d)
}

The output is something like:


---- repositories block ----
Delegate is of class class org.gradle.api.internal.artifacts.dsl.DefaultRepositoryHandler_Decorated
Method: public void DefaultRepositoryHandler_setProperty(String,Object) from class DefaultRepositoryHandler_Decorated
Method: public Object DefaultRepositoryHandler_getProperty(String) from class DefaultRepositoryHandler_Decorated
Method: public Class DefaultRepositoryHandler_getType() from class DefaultRepositoryHandler_Decorated
Method: public String DefaultRepositoryHandler_getDisplayName() from class DefaultRepositoryHandler_Decorated
Method: public FileResolver DefaultRepositoryHandler_getFileResolver() from class DefaultRepositoryHandler_Decorated
Method: public void DefaultRepositoryHandler_setConvention(Convention) from class DefaultRepositoryHandler_Decorated
...
Method: public void whenObjectAdded(Closure) from class AbstractDomainObjectCollection
Method: public Action whenObjectRemoved(Action) from class AbstractDomainObjectCollection
Method: public Set findAll(Spec) from class AbstractDomainObjectCollection
Method: public DomainObjectCollection withType(Class,Action) from class AbstractDomainObjectCollection
Method: public DomainObjectCollection withType(Class,Closure) from class AbstractDomainObjectCollection
...
Method: public final native void notify() from class Object
Method: public final native void notifyAll() from class Object
----------------------------

You could call printDelegateInfo in any similar block in Gradle, including a nested one. Just add the “d ->” at the beginning of your block to capture the delegate in a variable.

This trick is not as cool as autocomplete, but it can give you some clues. Note that a delegate’s method with a Closure argument means that you can probably create a block with that label and do more detailed configuration.

Lifting the blankets of Gradle

Gradle, the build system, is a DSL on top of Groovy. The build scripts (which are really configuration scripts) are Groovy code. So why do they look so weird?

Today I configured a particular obscure property of the eclipse plugin in milestone 6 of Gradle. The answer looks like:


apply plugin: 'eclipse-wtp'

eclipse {
wtp {
facet {
file {
whenMerged { config ->
config.facets.each {
if (it.name == 'jst.web') {
it.version = 3.0
}
}
config.facets.unique()
}
}
}
}
}

What is it doing? What is that “eclipse” word anyway? Is it a type? a variable? No — it is a method. The eclipse method (defined on the Project, but I’m not sure how) accepts a closure. Similarly, “wtp” is a method on EclipseModel, which accepts a closure. “facet” is a method on EclipseWtp.

But wait, how within the closure passed to the “wtp” method do we have access to a method on EclipseWtp? What determines that? The answer is: before calling our closure, Gradle sets some properties on the groovy.lang.Closure. The following snippet is modified for clarity from org.gradle.util.ConfigureUtil:


Closure copy = (Closure) configureClosure.clone();
copy.setResolveStrategy(Closure.DELEGATE_FIRST);
copy.setDelegate(delegate);
copy.call()

… where the delegate was passed in like so, in org.gradle.plugins.ide.eclipse.model.EclipseModel:


EclipseWtp wtp = new EclipseWtp()

void wtp(Closure closure) {
ConfigureUtil.configure(closure, wtp)
}

What happens is:
– wtp is a method that accepts our closure
– the wtp method sets an object of type EclipseWtp as the delegate on the closure
– the wtp method tells the closure to resolve methods on the delegate first.
– finally, the closure is called.

So, the strange scoping blocks in gradle turn out to be method calls. The way to find out what delegate you’re getting access to within each of these is to look at the DSL Reference or (for the real nitty-gritty details) the source code. For instance, the DSL Reference documentation for EclipseModel says that within the wtp {} block, you should see the documentation for EclipseWtp. (Note that the javadocs are useless. This is groovy trickery, not Java.)

This concept of a resolve strategy within a closure is interesting.