How to develop plugin with external dependencies, and then using the plugin in Gradle work on one of these dependencies?

We discovered something unexpected today while we were working on a plugin for managing interactions in a Continuous Delivery pipeline. The plugin has a dependency to a client API which is published by a client-server implementation. Of course we want to continue to develop the entire solution using itself as a CD solution but we found that this was not possible because of what looks like an internal bug in Gradle.

It will of course be easiest to demonstrate this problem with a demo project but we don’t have time to do that right now, so I am writing this first in the hopes that this may ring some bells at your end. If after all it is a known bug I don’t need to document it further.

So, if I have a buildscript with dependencies to the plugin (but not its runtime dependencies declared) and it itself has a dependency on this client artifact, then if I go back to work on the client/server project, which also has the plugin active when I am running gradle I get the following error:

FAILURE: Build failed with an exception.

  • What went wrong: Could not resolve all dependencies for configuration ‘:server:client:classpath’. > Module version group:wspgroup, module:wsp, version:1.4.4, configuration:default declares a dependency on configuration ‘default’

which is not declared in the module descriptor for group:servergroup, module:server, version:1.0.0

Now however, this project has no other reference to the module wsp other than in the buildscript.

Is this egg and chicken situation an unresolved problem in Gradle?

What is the best workaround? The only thing we can see now is swapping between a “development group” and a “release group” when we actually want to publish a new version of the client libraries - which isn’t very elegant at all…!

I can’t quite follow your explanations. Is the question about how to apply a plugin that lives in the same codebase? Does the plugin have to be shared with the rest of the world?

Maybe I need an example then.

plugin depends on a library

plugin is used when working on a new version of library

gradle complains that there is a dependency in gradle on default which is not declared in library (error message above).

Why?

Library has a static version dependency on library. It is not dynamic. It seems gradle gets very confused and thinks it should use the same dependency for the buildscript, as if I would have had the plugin and library in the same project (which we don’t) and had requested different versions of library, ie. resulting in a conflict which would be resolved by taking the latest highest number, but that isn’t possible because that hasn’t been built yet, so Gradle croaks and say: “but that doesn’t exist yet!”

An analogy would be when you are developing a new version of the Java plugin and use Gradle for doing that. How does that work? It doesn’t work for us.

Library has a static version dependency on library? What do you mean by that?

Sorry plugin has static version dependency on library. ie. 1.0.0 and not 1+. So we don’t understand why it would want to use 1.1.0 if that is what we were working on now.

What seems plausible to us is that it is identifying the resolved buildscript dependencies in the same space as the project dependencies we are working on.

You might be hitting GRADLE-2752.

We haven’t done the full investigation yet, but it looks like this was introduced in 1.5. Can you try with 1.4?

I tried it all the way to 1.2 and the bug exists all the way through. I will try to make an example of this over the weekend and share it with you.