Search code examples
gradleproguardshadowjar

How to reference the output file of an other Gradle task as ziptree?


I have a ShadowJar and a Proguard task that produce two jar files in my Gradle build.

task obfuscate(type: ProguardTask) {
  outjars ..
}

shadowJar {
  ...
}

task release(type: Jar) {
  from shadowJar
  from obfuscate
  classifier 'all'
}

My problem is that in this case the release jar file contains the shadow jar and the obfuscated jar files as two files in the jar itself. I would like to make these as zipTree inputs.

My problem is that I don't know how to turn the task reference into a zipTree of the actual output of that task.

My attempts lead me to from zipTree(shadowJar.outputs.getFiles()) but this still fails:

> Cannot convert the provided notation to a File or URI: task 'shadowJar' output files.
  The following types/formats are supported:
    - A String or CharSequence path, for example 'src/main/java' or '/usr/include'.
    - A String or CharSequence URI, for example 'file:/usr/include'.
    - A File instance.
    - A URI or URL instance.

How can I refer the output jar file of the preceding tasks properly?


Solution

  • Gradle docs on zipTree:

    Creates a new FileTree which contains the contents of the given ZIP file. The given zipPath path is evaluated as per Project.file(java.lang.Object).

    Therefor, zipTree can only handle single files, but outputs.files provides a file collection. This reveals two options:

    You can assume the task to provide a file collection containing only one file. In this case, you can simply take your approach and use the getSingleFile method:

    from zipTree(shadowJar.outputs.files.singleFile)
    

    As long as you use a task of type Jar, this should not cause any problems, because any task of this type will only create one jar file. But if you use other task types, that may have multiple output files (e.g. custom tasks), the getSingleFile method will fail.

    The second approach is to iterate over each output file, unzip it and add the revealed contents via from:

    shadowJar.outputs.files.each { outFile ->
        from zipTree(outFile)
    }
    

    I am not quite sure if the following works, but maybe its an even more Gradle-style solution:

    from shadowJar.outputs.files.collect{ zipTree(it) }