I have a zip that contains many jar files. Can I create a Gradle project that "builds" these jars by unzipping the file?

I am working with a project that ships binaries (compiled java classes) as a zip file. The zip contains various files, but the interesting ones are Java libraries packaged as JAR files inside the zip. The zip itself has been uploaded to my organization’s Artifactory.

Consider a structure like this:

project.zip

|- libs

| |- a.jar

| '- b.jar

|- resources

'- i18n

I have written a task that makes use of Copy to unzip the file contents, which works wonderfully.

task assemble(type: Copy) {
    assert configurations.main.files.size() == 1
      inputs.file configurations.main.files[0]
    outputs.file 'project/lib/a.jar'
      from zipTree(inputs.getFiles().getSingleFile())
    into projectDir
    include 'project/**'
      ant.chmod(dir: new File(projectDir, 'project/bin'), includes: '*', perm: 'ugo+rx')
}

However, the challenge I have is in figuring out how to “export” these files so that I can depend on them from another project. I suppose normally for Java projects (apply plugin java) this happens automagically since anything using the Jar task will be added to Gradle’s artifacts list for the current project.

What I would like to do is declare a dependency on this project from another, e.g.:

dependencies {
    compile project(':project')
}

and have the extracted jar files automatically added to the classpath.

Yes, this should be straight forward with copy task that runs zipTree on the artifact. You then need to define the output jars as artifacts of your project. Use the builtBy property to link the copy task to the artifacts.

Hi Casey,

Thanks for your reply!

I think I tried this, but was probably not doing it right. I already have the copy task, as you can see above.

I tried doing:

configurations {

archives }

artifacts {

archives assemble }

I also tried

artifacts {

archives fileTree(…) builtBy: assemble }

I think the latter option didn’t work because artifacts doesn’t take a FileCollection, only single files.

Any ideas?

First thing that may help you is to setup an global ‘artifacts’ task to inspect your configuration:

allprojects {
    task artifacts {
        group 'help'
        description "Display the artifacts associated with each configuration of ${project}"
        doFirst {
            configurations.findAll().each { config ->
                println "${config}:"
                config.allArtifacts.files.each { file ->
                    println "
" + file
                }
                println '------------------'
           }
     }
}

Heres an example where I expose an artifact built by an exec task called ‘build’…

artifacts {
    delegate.default file:build.outputs.files.singleFile, builtBy:build
}

‘delegate.default’ is how you access the “default” configuration object

Great, thank you. It looks like this will only add a single file as an artifact – would I then need some way to loop across all the files in the output fileTree?