Plugin dependencies

I have written a plugin (https://github.com/sebersole/gradle-animalSniffer-plugin) that defines dependency on specific versions it needs to run (org.codehaus.mojo:animal-sniffer:1.13 and org.ow2.asm:asm-all:5.0.3). I applied this plugin to a simple project and it worked fine. Yet, when I tried to apply this to the Hibernate build I run into a strange error:

Execution failed for task ':hibernate-core:compileJava'.
> java.lang.NullPointerException (no error message)
...
Caused by: java.lang.NullPointerException
    at org.codehaus.mojo.animal_sniffer.SignatureChecker$CheckingVisitor.find(SignatureChecker.java:502)

What makes this error strange is that this error seems to indicate that the execution of AnimalSniffer is somehow picking up a version of AnimalSniffer other than the one specific in my plugin (1.14 has a bug that leads to this exact NPE). I have no clue where it is picking 1.14 up from though. And I do not have any idea how to see the dependency tree for a plugin execution. The project dependency tree does not show any AnimalSniffer dependency, which is exactly what I expect.

Please help :smile:

I was able to verify this. Somehow AnimalSniffer 1.14 is being used, even though the plugin says to use 1.13. I added this to the plugin:

URL signatureCheckerLocation = getClass().getClassLoader().getResource( SignatureChecker.class.name.replace( '.', '/' ) + '.class' )
task.logger.lifecycle( "   -> Using AnimalSniffer SignatureChecker : ${signatureCheckerLocation.toURI().toURL()}" )

And get:

   -> Using AnimalSniffer SignatureChecker : jar:file:/home/sebersole/.gradle/caches/modules-2/files-2.1/org.codehaus.mojo/animal-sniffer/1.14/151548f12e21063df9acec3d0bcb2a1ee4df270f/animal-sniffer-1.14.jar!/org/codehaus/mojo/animal_sniffer/SignatureChecker.class

So how is AnimalSniffer 1.14 being picked even though (1) the plugin says to use 1.13 and (2) the project does not ever say to use anything but?

Furthermore, I was able to “get it to work” by explicitly re-listing the animal_sniffer and asm dependencies in the buildscript classpath of the project applying the plugin. This just seems like a bug in Gradle to me, or some very non-intuitive behavior:

buildscript {
    ...
    dependencies {
        // animalSniffer plugin specifies animal-sniffer:1.13 and asm-all:5.0.3 as dependencies
        classpath 'org.hibernate.build.gradle:gradle-animalSniffer-plugin:1.0-SNAPSHOT'

        // But Gradle does not pull those in transitively.  I guess it picks latest?  Either way, this is counter-intuitive at best.  So I am forced to define the same dependencies again.  ugh
        classpath 'org.codehaus.mojo:animal-sniffer:1.13'
        classpath 'org.ow2.asm:asm-all:5.0.3'
    }
}

This appears to give me a 1.13 animal sniffer. Could you check your cache and see if you have a POM for gradle-animalSniffer-plugin that has a different dependency in it (1.14 or a range)?

buildscript {
    repositories {
        mavenCentral()
        maven {
            url 'https://repository.jboss.org/nexus/content/repositories/snapshots'
        }
    }

    dependencies {
        classpath 'org.hibernate.build.gradle:gradle-animalSniffer-plugin:1.0-SNAPSHOT'
    }
}

task printBuildscriptClasspath << {
    println buildscript.configurations.classpath.asPath
}

Yes, I have a few that use 1.14; I was trying 1.14 before I understood that that version has a bug that affects me. No, I never use ranges.

What I completely cannot understand though is why it works from one build but not on another on the same machine. The cache is per-machine, so wouldn’t they find the same exact SNAPSHOT version?

Also, I run the builds right now with --refresh-dependencies and it makes no difference. Should that not force the build to use the latest SNAPSHOT version?

Completely deleting the ~/.gradle/caches/modules-2/files-2.1/org.hibernate.build.gradle/gradle-animalSniffer-plugin/1.0-SNAPSHOT directory had no effect anyway. The next build downloaded the latest SNAPSHOT form the repo with AS 1.13 specified (I verified it in the cached pom) but still it somehow pulls in AS 1.14. Could this be cached somehow in relation to the project applying the plugin? Is there a cache related to that project I could clean?

I am really stuck here. To me Gradle clearly seems to be doing something wrong. For sure something I did not intend.

Here is the dependency tree for the project using the plugin: https://gist.github.com/sebersole/9b8afa6b599affc314b2 gradle dependencies does not include buildscript dependencies (I have seen y’all discussing this on the dev list). I have no idea how to get the buildscript dependency tree, if that is even possible. But for whatever reason, Gradle is ignoring my plugin’s explicit dependencies and I have no idea why. :frowning:

And just to be super sure that this is not some craziness specific to SNAPSHOT resolution, I went ahead and published a Beta1 version and updated the Hibernate built to use that Beta1 version of the plugin. No change.

If I am doing something wrong, it is extremely non-obvious and I would love to hear from the developers what it is I am doing wrong. But I don’t think I am, and in my opinion this really needs to be a bug filed against Gradle.

And btw, now even explicitly declaring the AS and ASM dependencies in the Hibernate build buildscript has no effect. No matter what I try, Gradle is resolving AS in this build using versison 1.14.

Steve, can you provide the full buildscript repositories/dependencies for the failing project? I’d like to see if I can reproduce…

Sorry, I found the problem. I had left buildSrc (where I originally developed these plugins) in place and forgot to remove the reference to AS 1.14 in its build.gradle. I had to use --debug to find this out though:

...
09:38:18.467 [DEBUG] [org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.DependencyGraphBuilder] Visiting dependency :buildSrc:unspecified(runtime) -> org.codehaus.mojo:animal-sniffer:1.14(dependency: org.codehaus.mojo#animal-sniffer;1.14 {compile=[default]})
...

Would really have been helpful to see a dep-tree for the buildscript’s classpath config, which would have shown this…

Anyway, sorry for the noise.

This is something we are discussing at the moment on the dev mailing list.

https://groups.google.com/forum/#!topic/gradle-dev/2arhYw5PT5s

1 Like