Having trouble depending on a subproject's ZIP and exploding that ZIP locally

I have one subproject that pulls together files from other subprojects for distribution. An artifact of one of those other subprojects is a ZIP file. I’m having trouble making both of these happen at the same time:

  • Force the creation of the other subproject’s ZIP file if it hasn’t already been created * Explode the contents of that other ZIP file into my local project

And I’m hoping someone can see what I’m doing wrong.

Other Subproject:

defaultTasks 'distZip'
  task distZip(type:Zip) {
  // ...
}
  configurations {
  archive
}
  artifacts {
  archive distZip
}

Local Project:

configurations {
  archive
}
  dependencies {
  // Dep A:
  //archive
  project(path: ':tools:importer', configuration:'archive')
    // Dep B:
  archive
  project(path: ':tools:importer')
}
  task installServer(type: Copy) {
  // ...
    // Dep A: Builds tool ZIP, but just copies in unexploded version
  // Dep B: Builds tool JAR, puts its dependencies in 'tools', but nothing else
  //into("tools") {
  //
from(project.configurations.archive)
  //}
    // Dep A: Does not trigger dependency. If ZIP exists, explodes into root, not tools.
  // Dep B: Does not trigger dependency. If ZIP exists, does not use it. ***
  into("tools") {
    project.configurations.archive.each{
      from zipTree(it)
    }
  }
}

*** It looks like this combination explodes each of the dependent JARs, which I really don’t understand.

One more odd thing that I’ll mention in case it matters is that in the “Other” project I had to place the ‘configurations’ and ‘artifacts’ sections after the distZip task. Otherwise building the distZip task in that project gave me the message:

A problem occurred evaluating project ':tools:importer'.
> No such property: distZip for class: org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler

Version info:

------------------------------------------------------------ Gradle 2.1 ------------------------------------------------------------

Build time:

2014-09-08 10:40:39 UTC Build number: none Revision:

e6cf70745ac11fa943e19294d19a2c527a669a53

Groovy:

2.3.6 Ant:

Apache Ant™ version 1.9.3 compiled on December 23 2013 JVM:

1.7.0_21 (Oracle Corporation 23.21-b01) OS:

Mac OS X 10.8.5 x86_64

One necessary improvement is to defer iterating over the configuration until the end of the configuration phase:

into("tools") {
   from { project.configurations.archive.collect { zipTree(it) }
}

One more odd thing […]

That’s because you can only refer to a task object after it has been created.

Thanks for help, Peter. I made the change, but I’m seeing the same combination of results as before.

Dep A seems correct, as for some reason you aren’t using the ‘archives’ configuration which comes with plugins such as ‘java’, but instead create an ‘archive’ configuration, which has to be reflected in the project dependency. Based on the given information, it’s not clear to me why this would copy in the unexploded version. Perhaps check if the zip is generated correctly.

I didn’t realize the java plugin provided ‘archives’, so I changed to using it. It’s this:

from(project.configurations.archives)

that copies in the unexploded version, but that’s right isn’t it, since the other project’s archives artifact is a ZIP file?

This code:

from { project.configurations.archives.collect { zipTree(it) } }

does explode the ZIP file (albeit not into the directory I specified), but it doesn’t seem to trigger the creation of the ZIP file. It only works if the ZIP file had already been created.

As far as I can tell the ZIP file is created OK when I run Gradle in the other project directory. I’m going to create a scaled-down project to try and recreate this. Thanks for your help, Peter.

but it doesn’t seem to trigger the creation of the ZIP file […]

Yeah that’s right. With the second ‘from’ line, Gradle won’t be able to infer the task dependency by itself, and you’ll have to add one explicitly: ‘dependsOn(’:tools:importer:distZip’)’.

Thank you. That worked, as did

dependsOn(project.configurations.archives)

which I decided to use.

That’s even better.