Gradle 2.4 - Cache unreliable

Ok, that sounds more flexible than what I’m currently doing.

How would I access the generated files/binaries in the dependent project/task then? And do I have to create a ZIP file for the artifact and then unzip it again? (According to the documentation, ArtifactHandler expects an AbstractArchiveTask.) Because that seems like overkill for passing a few files from one subproject to another.

Yes, you would typically pass the files in the form of a bundled archive. This is the “proper” way to model this type of cross-project dependency. Also, in a way, defining strict lines of separation helps identify instances in where your project structure is perhaps non-optimal.

The benefit of this type of dependency is that it is explicit. By declaring a project dependency you are establishing a contract between that project and others. By essentially “reaching over” into other projects to consume output from their tasks, we are creating a very brittle scenario, in which changes to build implementation build details might cause issues (as we’ve already seen).

True, our previous Maven build had a lot of flaws, not all of which were Maven’s fault. (It’s a huge project and the build configuration grew over time.) During the migration to Gradle they’re now becoming more obvious. I still wish there’d be a way to define a set of files (folder) as an artifact and skip the archiving step.

I’ll try to figure out the easiest way to pass source files and regular files between subprojects via artifacts now. Thanks a lot for your help so far.

An intermedium would be to declare your input to be the generate task itself. This both solves the problem of not hard-coding against a particular output directory and creates and inferred dependency between tasks (which should facilitate parallel builds).

inputs.files files(project(':otherProject').generate)

That doesn’t work for me, gradle is telling me that the property generate doesn’t exist on the other project.

Probably an evaluation ordering issue. Try adding evaluationDependsOn(':otherProject') to your build script.

Thanks, that did the trick

Note that having to explicitly declare an evaluation order is an indication that Gradle does not know that there is a dependency between these two projects. This is precisely the reason why using project dependencies (as I showed above) is the more correct way to model these types of inter-project dependencies.

I’m still having some trouble trying to understand how configurations and tasks interact, though. How do I tell gradle that tasks belong to a specific configuration and that therefore the configuration’s dependencies should run before any of those tasks? And how do I specify the dependency between the builtin configuration (compile) and my generatedFiles configuration then?

Essentially you add artifacts (usually the output of some kind of archive task) to a configuration in the producing project. Then you add a dependency to that configuration in a dependent project and assign the dependency to a configuration. A Configuration is really just a FileCollection so you can treat it as such.

Take a look at the docs on ArtifactHandler for more details.

That’s the part I get. What I don’t get is how to tell gradle which tasks belong to the dependent configuration in the dependent project, i.e. which tasks in the dependent project depend on the artifact of the producing project. Also, is there an easier way to specify a dependency between different configurations in a single subproject than using project(path: ':myself', configuration: 'other_configuration')?

You would simply declare the configuration as an input of that task.

No, not currently.

Ah, that’s the part I was missing.

OK, I just suspected there might be a more elegant version. Thanks again for your help!

Just one last question, to make sure I understood this correctly: So I basically need two additional configurations in projectB, then, right? One to specify the dependencies on projectA's generatedFiles artifact, which I use as an input to projectB's own generation tasks. And one to hold projectB's own generatedFiles artifact which other subprojects can then consume?

Yes, that is correct.