Task ':app:compileDebugAidl' class path has changed


(Stefan Wolf) #6

I still don’t have enough information to get some ideas…
Could you add the following snippet to your build.gradle:

import org.gradle.internal.classloader.ClassLoaderVisitor
import org.gradle.internal.classloader.ClassLoaderHierarchyHasher

def hasher = gradle.services.get(ClassLoaderHierarchyHasher)

gradle.buildFinished {
  def task = project(':app').compileDebugAidl
  new Visitor(hasher, task).visit(task.getClass().getClassLoader())
}

class Visitor extends ClassLoaderVisitor {
    final ClassLoaderHierarchyHasher hasher
    final String prefix
    int counter

    Visitor(ClassLoaderHierarchyHasher hasher, Task task) {
        this(hasher, "${task.path}-classloader")
    }

    Visitor(ClassLoaderHierarchyHasher hasher, String prefix) {
        this.hasher = hasher
        this.prefix = prefix
    }

    private String classloaderHash(ClassLoader loader) {
        def hash = hasher.getClassLoaderHash(loader)
        if (hash != null) {
            return hash.toString()
        } else {
            null
        }
    }

    @Override
    void visit(ClassLoader classLoader) {
        def hash = classloaderHash(classLoader)
        if (hash) {
            def classloaderName = classLoader.getClass().getSimpleName()
            println "${prefix}-${counter++}-${ classloaderName}-hash:  $hash"
            if (classLoader instanceof URLClassLoader && (!classloaderName.contains('ExtClassLoader'))) {
                println "${prefix}-${counter - 1}-classpath ${classLoader.getURLs().join(':')}"
            }
        }
        super.visit(classLoader)
    }
}

This will print out the classloader hashes of the classloader of the class and its parents. If you could provide the output for running compileDebugAidl in IDEA and on the commandline I probably will have a better idea what is actually different. Either post the output here or send it to me via mail.

Thank you very much for your help in getting to the root of the issue!


(Fabian Zeindl) #7

Sure.
Thank you for the help, I really appreciate it.
Fixing this will save me and potentially others many flow-breaking minutes of waiting per day.


(Stefan Wolf) #8

Hi Fabian.

Thank you again for the logs you sent me.
After looking closer at the issue it seems that Android studio injects a custom file repository into the Gradle build. For some reason, when using the custom repository, antlr 3.5.2 is not added to the build script classpath, while it is added when running from the command line.
It seems that Android Studio 3.0 (beta 6 at the time of writing) should not do that any more. Could you verify that the task is up to date when using Android Studio 3.0?

Cheers,
Stefan


(Fabian Zeindl) #9

Hi, Stefan

I just installed AS3-beta6 and sadly the issue isn’t fixed. I have generated the same logs again and sent them per email.


(Stefan Wolf) #10

Hi Fabian,

thanks again for the logs. It looks like nothing changed. Could you also try using the latest Android plugin for Gradle? Here are migration instructions: https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html
What you also could try is to exclude antlr:3.5.2, since these are the offending artifacts which are present in the buildscript classpath when running from the console:

buildscript {
    configurations.classpath.exclude group: 'org.antlr', module: 'antlr'
    configurations.classpath.exclude group: 'org.antlr', module: 'antlr-runtime'
    configurations.classpath.exclude group: 'org.antlr', module: 'ST4'
}

Cheers,
Stefan


(Stefan Wolf) #11

Hi Fabian,

on another note, it seems like the problem is not Gradle related at all, but more a problem with Android Studio/the Android plugin for Gradle. Could you open an issue for the Android plugin for Gradle?

Cheers,
Stefan


(Fabian Zeindl) #12

Hi Stefan,

I’m using classpath 'com.android.tools.build:gradle:3.0.0-beta6'already, since the gradle-plugin version must always be tied to the Android-Studio version.

I’ve reported a bug: https://issuetracker.google.com/issues/66936393

I hope someone will look at it. These “minor” bugs tend to get ignored, but it is my opinion that improving build-performance and caching is a multiplicator that increases quality-of-software (and quality-of-life) everywhere.

In that sense thank you again for your time looking at this.


(Fabian Zeindl) #13

Also I tried the tip with the exclusions, but no difference.


(Stefan Wolf) #14

Hi Fabian,

I did something wrong when looking at the second set of logs with Android Studio 3.0 (I looked at the wrong log files). Actually, it seems that all the jars are the same (same name, same version). It could be possible that one of the jars has a different content. Do you use any custom repositories in your build script? I could send you a script to get the md5 sums of all the libraries involved and then we could compare those. Would you be willing to try that out?

Cheers,
Stefan


(Stefan Wolf) #15

This would be the code you would need to add to your build script:

import org.gradle.internal.classloader.ClassLoaderVisitor
import org.gradle.internal.classloader.ClassLoaderHierarchyHasher
import org.gradle.internal.hash.FileHasher

def hasher = gradle.services.get(ClassLoaderHierarchyHasher)
def fileHasher = gradle.services.get(FileHasher)

gradle.buildFinished {
  def task = project(':app').compileDebugAidl
  new Visitor(hasher, fileHasher, task).visit(task.getClass().getClassLoader())
}

class Visitor extends ClassLoaderVisitor {
    final ClassLoaderHierarchyHasher hasher
    final String prefix
    final FileHasher fileHasher
    int counter

    Visitor(ClassLoaderHierarchyHasher hasher, fileHasher, Task task) {
        this(hasher, fileHasher, "${task.path}-classloader")
    }

    Visitor(ClassLoaderHierarchyHasher hasher, FileHasher fileHasher, String prefix) {
        this.hasher = hasher
        this.prefix = prefix
        this.fileHasher = fileHasher
    }

    private String classloaderHash(ClassLoader loader) {
        def hash = hasher.getClassLoaderHash(loader)
        if (hash != null) {
            return hash.toString()
        } else {
            null
        }
    }

    @Override
    void visit(ClassLoader classLoader) {
        def hash = classloaderHash(classLoader)
        if (hash) {
            def classloaderName = classLoader.getClass().getSimpleName()
            println "${prefix}-${counter++}-${ classloaderName}-hash:  $hash"
            if (classLoader instanceof URLClassLoader && (!classloaderName.contains('ExtClassLoader'))) {
                println "${prefix}-${counter - 1}-classpath ${classLoader.getURLs().join(':')}"
                classLoader.getURLs().each { url ->
                    println "${url}: ${fileHasher.hash(new File(url.toURI()))}"
                }
            }
        }
        super.visit(classLoader)
    }
}

(Fabian Zeindl) #16

FileHasher can’t be resolved…


(Stefan Wolf) #17

Strange. I just tried it and it works for me. Did you copy all of the above to the top-level of your build file? In which line does the problem (“FileHasher can’t be resolved”) occur?


(Stefan Wolf) #18

@fab1an Any chance on running my latest diagnostics script or reporting the error which occurred for you?


(Fabian Zeindl) #19

Not at the moment, I’ll get back at you next week.


(Fabian Zeindl) #20

It says that import org.gradle.internal.hash.FileHasher cannot be resolved.

I replaced the relevant line with:

println "${url}: ${HashUtil.sha1(new File(url.toURI())).asHexString()}"

and sent you the results per mail.


(Stefan Wolf) #21

Hi Fabian.

Thank you very much for the new logs. I would still like to understand why org.gradle.internal.hash.FileHasher can’t be resolved for your project, but it doesn’t really matter for the problem we are trying to solve (it would be great if you could provide me with a full stacktrace).
The sha1s of the files are sufficient. It seems like the Android plugin jars shipped with Android studio are different from the ones in your Gradle repository cache. E.g. <home>/.gradle/caches/jars-3/d15c489eefc089360ed43525f2f8dd09/gradle-3.0.0-beta6.jar is different to <home>/.gradle/caches/modules-2/files-2.1/com.android.tools.build/gradle/3.0.0-beta6/948b8c05b40b5f607a49d58e7c66a95faa61134f/gradle-3.0.0-beta6.jar. These jars should actually be the same. Please have a look at the diff of these to files to get an understanding what happened there.
I think we cannot do something in Gradle to fix this problem but the Android plugin/Android Studio needs to be fixed to either

  • not ship a file repository
  • ship the same artifacts in the file repository as are uploaded in the public maven repository.

I would prefer if they just would not configure a file repository in Android Studio at all.

Cheers,
Stefan


(Fabian Zeindl) #22

Hi Stefan,

all-right it looks like Google has to do some work here.
Thank you again for your time.

Regarding the other (for-me-unimportant ;)) issue: I’m using the gradle-wrapper with sources, and this is all that AStudio is able to resolve in the package:


(Fabian Zeindl) #23

The difference seems to be in signing. Android ships an additional

> META-INF/GOOGLE_O.RSA
> META-INF/GOOGLE_O.SF

(Fabian Zeindl) #24

Stefan, I now use Android Studio 3, the problem has shifted slightly. Can you look at my problem here:


(Stefan Wolf) #25

This should be fixed in Android Gradle plugin 3.1. Can you confirm?