javagradlecopymeta-inf

Copying META-INF from all dependencies using gradle copy task


An issue with using a Gradle Copy task:

def loopJar(File file) {
    zipTree(file).findAll { that ->
        that
    }.collect { the ->
        if (the.getName().endsWith(".jar") || the.getName().endsWith(".aar")) {
            loopJar(the)
        }
        the;
    }
}

task fatJar(type: Copy) {
    into 'libs'
    include { it.toString().contains("META-INF") }
    from {
        configurations.compile.findAll {
            it.getName() != 'android.jar'
        }.collect {
            loopJar(it);
        }
    }
}

Pretty simple, loop through all dependencies, if they're archives, loop through their zipTrees to make sure that they don't have Jar in themselves.

Once I've done this, I want to copy all the files from the META-INF folders into my directories.

For some reason, It's copying ALL files into the directory. However, if I println in eachFile, it only displays the files that I want copying.

      file '/{Dir Structure Here}/build/tmp/expandedArchives/activeandroid-3.1.0-SNAPSHOT.jar_duhgtuy24rfyj4gq0cc29tyjl/META-INF/MANIFEST.MF'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-annotations-2.4.1.jar_asorliiuo3vke643z99zgpvqb/META-INF/LICENSE'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-annotations-2.4.1.jar_asorliiuo3vke643z99zgpvqb/META-INF/MANIFEST.MF'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-annotations-2.4.1.jar_asorliiuo3vke643z99zgpvqb/META-INF/maven/com.fasterxml.jackson.core/jackson-annotations/pom.properties'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-annotations-2.4.1.jar_asorliiuo3vke643z99zgpvqb/META-INF/maven/com.fasterxml.jackson.core/jackson-annotations/pom.xml'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-databind-2.4.1.3.jar_av3gri85ykjeek8zq4zffxj7c/META-INF/LICENSE'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-databind-2.4.1.3.jar_av3gri85ykjeek8zq4zffxj7c/META-INF/MANIFEST.MF'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-databind-2.4.1.3.jar_av3gri85ykjeek8zq4zffxj7c/META-INF/NOTICE'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-databind-2.4.1.3.jar_av3gri85ykjeek8zq4zffxj7c/META-INF/maven/com.fasterxml.jackson.core/jackson-databind/pom.properties'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-databind-2.4.1.3.jar_av3gri85ykjeek8zq4zffxj7c/META-INF/maven/com.fasterxml.jackson.core/jackson-databind/pom.xml'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-databind-2.4.1.3.jar_av3gri85ykjeek8zq4zffxj7c/META-INF/services/com.fasterxml.jackson.core.ObjectCodec'
file '/{Dir Structure Here}/build/tmp/expandedArchives/support-annotations-23.1.1.jar_59cc6fqykevukbtu3fq75wbi0/META-INF/MANIFEST.MF'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-core-2.4.1.1.jar_cf7fa55yohvqtmkkzf26lmy55/META-INF/LICENSE'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-core-2.4.1.1.jar_cf7fa55yohvqtmkkzf26lmy55/META-INF/MANIFEST.MF'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-core-2.4.1.1.jar_cf7fa55yohvqtmkkzf26lmy55/META-INF/NOTICE'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-core-2.4.1.1.jar_cf7fa55yohvqtmkkzf26lmy55/META-INF/maven/com.fasterxml.jackson.core/jackson-core/pom.properties'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-core-2.4.1.1.jar_cf7fa55yohvqtmkkzf26lmy55/META-INF/maven/com.fasterxml.jackson.core/jackson-core/pom.xml'
file '/{Dir Structure Here}/build/tmp/expandedArchives/jackson-core-2.4.1.1.jar_cf7fa55yohvqtmkkzf26lmy55/META-INF/services/com.fasterxml.jackson.core.JsonFactory'

That's the output of eachFile. Yet all files are going into the libs folder... What!?

The usage of this script: To copy all meta-inf files (Eventually just Licensing, notice information) and add them to my AAR file in their own folders to allow others wishing to include my aar to do so without the conflicing file issues: Android Gradle plugin 0.7.0: "duplicate files during packaging of APK"


Solution

  • def loopJar(files, Map l) {
        files.findAll {
            if (!(it instanceof File))
                return false;
            it.getName() != 'android.jar'
        }.collect { file ->
            List e = new ArrayList();
            zipTree(file).each { the ->
                if (the.getName().endsWith(".jar") || the.getName().endsWith(".aar")) {
                    loopJar(the, l)
                }
                if (the.getPath().contains("META-INF"))
                    e.add(the);
            }
            if(!e.isEmpty())
            l.put(file.getName(), e);
        }
    }
    
    task fatJar << {
        Map l = new HashMap();
        loopJar(configurations.compile, l);
        l.each { key,val ->
            val.each {
                copy {
                    from val
                    into "licensing/"+key+"/"
                }
            }
        }
    }
    

    Simple enough fix: Write it the Java way.