As a few have, I stumbled into this $$ jacoco bug. To be fair this is not so much a GradlePlugin bug as more Jacoco/Dagger.

Semantics aside, we wanted to know about our unit test coverage with Robolectric.

Implimentations vary, I based alot of my work off of this template.

Unlike the template I decided to embed Jacoco into my main project. (Maybe a jacoco.gradle file might be better, but thats trivial).

At time of writing we use:

  • Gradle 1.12
  • Android Gradle Plugin 0.11.+
  • Robolectric plugin 0.11.+


// ^^^ Other build stuff up here ^^^

apply plugin: "jacoco"

jacoco {  
    // I have only tried 0.7.x
    toolVersion = ""
// Define coverage source.
// If you have rs/aidl etc... add them here.
def coverageSourceDirs = [  

// This differs per what flavors buildTypes etc. 
// But this example shows the 'testDebug'
// which is standard for Robolectric
task jacocoTestReport(type: JacocoReport, dependsOn: "testDebug") {  
    group = "Reporting"
    description = "Generate Jacoco coverage reports after running tests."
    reports {
        xml.enabled = true // coveralls plugin depends on xml format report
        html.enabled = true
    // class R is used, but usage will not be covered, so ignore this class from report
    // This differs per plugin version (0.10 -> 0.11) 
    // have very different fileTrees.
    // I have added rules to Ignore Dagger/Butterknife
    classDirectories = fileTree(
            dir: './build/intermediates/classes/debug',
            excludes: ['com/myapp/R*.class',
    sourceDirectories = files(coverageSourceDirs)
    executionData = files('build/jacoco/testDebug.exec')
    // Bit hacky but fixes
    // We iterate through the compiled .class tree and rename $$ to $. 
    doFirst {
        new File('myapp/build/intermediates/classes/').eachFileRecurse { file ->
            if ('$$')) {
                file.renameTo(file.path.replace('$$', '$'))
    afterEvaluate {
        // just clean up coveralls dashboard, following reports are not of interest
        testDebug.reports.junitXml.enabled = false

Run: $ ./gradlew jacocoTestReport


I recommend you clean then assemble if you are going to build an app after testing.

The $$ -> $ shouldn't break anything, but it's better to be safe than sorry especialy as Dagger and Butterknife use partial reflection to look up some of the generated classes.


By no means is this script 100% but its about as concise as I could get it for my use case. As the $$ bug has been around since 2011, no one seems to want to fix it. Until then, I can't see any detrimental effect of just renaming the files.

Also I don't care so much about Android Studio / Intelij intergration, we use CI and build stats.
Push & forgot, CI tests and warns.

Follow up

I will add to this when I get ([] up and running.