Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable META-INF/* generation in gradle android library kotlin project

Good day. I've written a kotlin android library and uploaded it on bintray. But when I try to use it (via gradle compile) in some project, it fails to build with following errors:

> com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/library_release.kotlin_module
File1: C:\Users\Charlie\.android\build-cache\2939fbc6b0336396c9c4912d615880645b2c729d\output\jars\classes.jar
File2: C:\Users\Charlie\OneDrive\Dev\Projects\AndroidStudio\MetuCardLib\demo\build\intermediates\bundles\default\classes.jar

I've looked up both of these .jar files and they both contained META-INF folder with library_release.kotlin_module file. But more importantly generated .aar (android archive published in bintray) contained this folder as well as this file. I've checked other decent bintray android libraries and they don't seem to include any META-INF files. However those that do include it (in most cases they contain license files) produce the same DuplicateFileException and the way to resolve it is to explicitly exclude them in use-project's gradle file.

What's the use of this library_release.kotlin_module file and how can I disable its generation during publishing? Because I don't want to explicitly exclude from every project which is using this library and I don't want to ask other developers to do so.

Here's the library's repo: https://github.com/arslancharyev31/Anko-ExpandableTextView/ And it's bintray repo: https://bintray.com/arslancharyev31/android/Anko-ExpandableTextView

like image 704
arslancharyev31 Avatar asked Jul 21 '17 08:07

arslancharyev31


Video Answer


1 Answers

The original purpose of .kotlin_module files is to store the package parts mapping to the compiled class files. The compiler uses them to resolve top-level function calls in a library attached to the project. Also, Kotlin reflection uses the .kotlin_module files to construct the top level members metadata at runtime. See more: Improving Java Interop: Top-Level Functions and Properties

Given that, you don't want to disable their generation in library projects, because it might break compilation against the libraries.

Instead, you can get rid of the duplicates by using packagingOptions in your app build.gradle, as said here:

android {
    // ...

    packagingOptions {
        exclude 'META-INF/library_release.kotlin_module'
    }
}

Note: excluding these files from an application APK interferes with reflection at runtime and therefore is is not the best solution either.


Another option is to use unique module names in your libraries:

compileReleaseKotlin.kotlinOptions.freeCompilerArgs += ["-module-name", "my.library.id"]

Choose the task that produces the output that is then packed into the AAR. It might not be compileReleaseKotlin, and also note that doing this might affect the tests compilation for this variant.

Or, what's more reliable, just choose unique Gradle module names, because the Kotlin module is named after the Gradle project.

like image 81
hotkey Avatar answered Sep 22 '22 05:09

hotkey