Using zipTree in copy when archive has duplicate files causes UncheckIOException


(bob.lloyd.1981) #1
repositories{
    mavenCentral()
}
configurations{
   myConfig
}
dependencies{
  myConfig 'org.apache.storm:storm-core:0.9.4'
}
task unpackJar(type: Copy){
  configurations.myConfig.collect{from zipTree(it)}
}

Using the above code, I get a stack trace similar to:

Caused by: org.gradle.api.GradleException: Could not copy zip entry /Users/builder/.gradle/caches/modules-2/files-2.1/org.apache.storm/storm-core/0.9.4/e1edab89bfcabebca6b603cf0b06c239f0010fff/storm-core-0.9.4.jar!META-INF/license/LICENSE.base64.txt to '/Users/builder/build/tmp/expandedArchives/storm-core-0.9.4.jar_4vs05w0k35c2grjityjszrhso/META-INF/license/LICENSE.base64.txt'.
    at org.gradle.api.internal.file.AbstractFileTreeElement.copyTo(AbstractFileTreeElement.java:79)
    at org.gradle.api.internal.file.archive.ZipFileTree$DetailsImpl.getFile(ZipFileTree.java:126)
    at org.gradle.api.internal.file.AbstractFileTree$1.visitFile(AbstractFileTree.java:40)
    at org.gradle.api.internal.file.AbstractFileTree$FilteredFileTree$1.visitFile(AbstractFileTree.java:146)
    at org.gradle.api.internal.file.archive.ZipFileTree.visit(ZipFileTree.java:91)
    ... 67 more
Caused by: org.gradle.api.UncheckedIOException: Cannot create directory '/Users/builder/build/tmp/expandedArchives/storm-core-0.9.4.jar_4vs05w0k35c2grjityjszrhso/META-INF/license' as it already exists, but is not a directory
    at org.gradle.util.GFileUtils.mkdirs(GFileUtils.java:268)
    at org.gradle.api.internal.file.AbstractFileTreeElement.copyTo(AbstractFileTreeElement.java:73)
    ... 71 more

In the contents of storm-jar, there is a META-INF/LICENSE file, and a META-INF/license folder (of course, don’t get me started on archives that contain duplicate entries!). This code seems to work on a *nix machine, but does not work on MacOSX, and from past experiences, probably does not work on Windows.

I tried to exclude the META-INF/LICENSE file from the unpack, but it doesn’t seem to work, as Gradle seems to want to expand the entire archive before selecting files out to copy. A possible solution might be to selectively expand the archives to other temporary folders, then aggregate the contents, but I’m not sure how/if that would work. It would be nice if there was a way to tell the zipTree functionality to “overwrite” duplidates, and force expansion.