I am using the shadow plugin for Gradle to generate modified jars for Dagger 2. The jar files are generated as expected, but when I add the jars as dependencies to my proyect i get
Error:Execution failed for task ':transformClassesAndResourcesWithSyncLibJarsForRelease'.
> java.util.zip.ZipException: duplicate entry: META-INF/maven/com.google.dagger/dagger/pom.properties
To give toy the context of my case: I have an app with the next structure
CoreLib
|
Lib1
|
App
CoreLib and Lib1 uses these jar files generated by shadow to replace dagger2. But when running the app I get the previous exception in Lib1.
I add the jars like this in both libraries
apt files('libs/two-daggers-compiler-1.0.0.jar')
compile files('libs/two-daggers-library-1.0.0.jar')
Any ideas??
The solution for my problem was that I had to exclude the duplicated files.
I added this to my application buid.gradle and the problem was solved.
packagingOptions {
exclude 'META-INF/maven/com.google.dagger/dagger/pom.xml'
exclude 'META-INF/maven/com.google.dagger/dagger/pom.properties'
}
I added it in the android block
Related
I'm developing an android library for work and we're using some jars that are not available in maven repositories. However, we are not legally allowed to package these jars into our library, the consumer must get those jars themselves in addition to our library.
My problem is that I can't seem to require the consumer of our library to provide these jars (I'm using a test app that includes the aar). I tried the solutions for this similar question to no avail.
I have tried setting them to provided instead of compile in my gradle file:
// Neither of these seem to fix the problem
compile files('libs/externalDep.jar')
provided files('libs/externalDep.jar')
I also tried excluding them in packaging options:
packagingOptions { exclude 'libs/externalDep.jar }`
I can exclude them by adding this to the android tag in my build.gradle:
android.libraryVariants.all { variant ->
variant.outputs.each { output ->
def packageLib = output.getPackageLibrary()
packageLib.exclude('libs/externalDep.jar')
}
They're not added to the aar but building the test app gives me:
com.android.build.api.transformTransformException:
com.android.builder.packaging.DuplicateFileException:
Duplicate files copied in APK VERSION.txt
File1: path/to/jar/in/test/app/project/externalDep.jar
File2: path/to/build/intermediates/exploded-aar/.../jars/classes.jar
To clarify, I'm not concerned at all with maven repo dependencies, those are working fine. I just want whoever uses the library to have to get and add those jars we're using too.
Surely there's a less convoluted way to specify this?
The jar file must be moved up one level, from mymodule/libs/ to mymodule/ as per this answer.
Then in the build.gradle file, change:
compile file('libs/externalDep.jar')
to
provided file('externalDep.jar')
That's it.
It won't be copied into the aar and clients using the aar must provide the jar file themselves.
App projects using the aar can specify compile file('lib/externalDep') as normal.
I have used 2 third party aar dependencies in my Android Project and
they both are using same Encoding Library called org.spongycastle.util.
But problem here is when i compiled it it shows an Error on Gradle
Error:Execution failed for task ':app:transformClassesWithJarMergingForDebug'.
> com.android.build.api.transform.TransformException:java.util.zip.ZipException: duplicate entry: org/spongycastle/util/encoders/Base64.class
I tried to exclude one dependency from aar on Gradle complie by
compile(name: 'libraryname', ext: 'aar') {
exclude group: 'org.spongycastle.util'
}
But no luck of solving issue :(
Any help would be appreciated to exclude or ignore one dependency
It looks like the jar file org.spongycastle.util itself contains the duplicate entry. I've seen this same issue in an xmlbean jar file. Android however doesn't like the duplicate entry. One way to get around this is to download that particular jar file and delete one of the duplicate entries and add the modified jar to your libs folder. Additionally, you'll need to exclude it from the appropriate compile dependency it is associated with. You'll need to test to be sure that deleting one of the duplicates doesn't break anything. If the contents of the two duplicate classes are equivalent, then deleting one of the duplicates wouldn't have any consequence.
We are working on an application (APP) that uses a local maven dependency library (LIB). LIB uses a custom .jar of OkHttp, and APP also uses OkHttp (not custom). When we try to build, we get a 'Multiple dex files define X' error, and enabling multiDex gives an error about a duplicate ZipException. APP is trying to refer to the OkHttp.jar in LIB, when we want it to not do that. And, well, we can't get it to work.
We've tried placing this in our APP gradle file with no luck:
compile(LIB) {
exclude group: 'com.squareup', module: 'okhttp';
}
And, unfortunately, we can't not use LIB. Thoughts? Also, gradle -q dependencies does not list any dependencies under LIB, but we know that it uses a compile file('CUSTOM_OKHTTP') line in its gradle.
Following various sets of instructions, it seems that I should add native libraries to app/src/main/jniLibs and they'll be linked up automagically. However when I do this (for OpenCV) I get the following:
Error:duplicate files during packaging of APK /.../app/build/outputs/apk/app-debug-unaligned.apk
Path in archive: lib/armeabi/libopencv_java.so
Origin 1: /.../app/src/main/jniLibs/armeabi/libopencv_java.so
Origin 2: /.../build/intermediates/exploded-aar/AppName/.libraries/opencv/unspecified/jni/armeabi/libopencv_java.so
You can ignore those files in your build.gradle:
android {
packagingOptions {
exclude 'lib/armeabi/libopencv_java.so'
}
}
Error:Execution failed for task ':app:packageDebug'.
> Duplicate files copied in APK lib/armeabi/libopencv_java.so
File 1: /.../app/src/main/jniLibs/armeabi/libopencv_java.so
File 2: /.../app/src/main/jniLibs/armeabi/libopencv_java.so
Adding the exclude section doesn't work. There's only one copy of the file, but somehow it's being referenced twice, and it seems the second (build) include is something auto-generated. What can I do?
In case of duplicate libraries (*.so) files, exclude option will not help as we cannot completely exclude the native binaries. There is one more option in packagingOptions. It is 'pickFirst'. We can avoid duplicate files error and include the first one the compiler encounters.
packagingOptions {
pickFirst 'lib/armeabi/libopencv_java.so'
}
ndk-build was generating duplicates of all of the packages from OpenCV. I removed all of the .so libraries from my app, apart from my actual app library, and then it packaged up fine.
I also had this issue. It seems it's because the documentation and various conversation threads on setting up OpenCV for Android say to put the JNI libraries at the path /src/main/jniLibs or /src/main/libs. The problem is that the /src/ folder is for source code, not libraries. The solution is to move the /main/ folder out of /src/ and into the project root, which is how Google documents this project structure: https://developer.android.com/tools/projects/index.html
I also have the following settings in build.gradle:
android {
sourceSets {
main {
jni.srcDirs = [] //disable automatic ndk-build call
jniLibs.srcDir 'main/libs'
}
}
}
I get a "duplicate files" conflict when building a parent project with two library modules, which make use of the same libc++_shared.so shared library.
(NOTE: Please do not consider this a "duplicate question". I have read several related posts, which have helped me get this far. However, no posts have provided an answer that works in my case involving NDK artifacts.)
The build was working correctly when I only had 1 such library module. The addition of the second library module is now creating the conflict.
Consider the following project structure: 1 parent project, 2 "child" projects - but each project is located at the same directory level (i.e. Not nested hierarchically)
ProjectA/ (Parent)
LibraryModuleA1/
build/exploded-aar/com.package.name/
LibraryModuleB1/<version>/jni/armeabi-v7a/libc++_shared.so
LibraryModuleC1/<version>/jni/armeabi-v7a/libc++_shared.so
build.gradle (bgA1)
Test_APK_Module A1T/
build.gradle (bgA1T)
build.gradle (bgPA)
ProjectB/
LibraryModuleB1/ (Uses NDK)
build/lib/armeabi-v7a/libc++_shared.so
build.gradle (bgB1)
build.gradle (bgPB)
ProjectC/
LibraryModuleC1/ (Uses NDK)
build/lib/armeabi-v7a/libc++_shared.so
build.gradle (bgC1)
build.gradle (bgPC)
Library Module A1 depends on both Library Modules B1 & C1.
A1 -> B1
A1 -> C1
Projects B and C both have NDK-based code and build/test correctly. Both depend on the libc++_shared.so shared library.
However, when building Project A, I get the following error during the :LibraryModuleA1:packageDebugTest task:
Error: duplicate files during packaging of APK /ProjectA/LibraryModuleA1/build/apk/LibraryModuleA1-debug-test-unaligned.apk
Path in archive: lib/armeabi-v7a/libc++_shared.so
Origin 1: /ProjectA/LibraryModuleA1/build/exploded-aar/com.package.name/LibraryModuleB1/<version>/jni/armeabi-v7a/libc++_shared.so
Origin 2: /ProjectA/LibraryModuleA1/build/exploded-aar/com.package.name/LibraryModuleC1/<version>/jni/armeabi-v7a/libc++_shared.so
You can ignore those files in your build.gradle:
android {
packagingOptions {
exclude 'lib/armeabi-v7a/libc++_shared.so'
}
}
* What went wrong:
Execution failed for task ':LibraryModuleA1:packageDebugTest'.
> Duplicate files copied in APK lib/armeabi-v7a/libc++_shared.so
File 1: /ProjectA/LibraryModuleA1/build/exploded-aar/com.package.name/LibraryModuleC1/<version>/jni/armeabi-v7a/libc++_shared.so
File 2: /ProjectA/LibraryModuleA1/build/exploded-aar/com.package.name/LibraryModuleC1/<version>/jni/armeabi-v7a/libc++_shared.so
:LibraryModuleA1:packageDebugTest FAILED
What I've Tried So Far
I attempted to add the suggested closure to my build.gradle file, but which build.gradle file do I add it to? I have added the closure to bgA1, bgB1, and bgC1 (one at a time), with no success.
The suggested closure says to use exclude 'lib/armeabi-v7a/libc++_shared.so'. Each "child" library module builds the libc++_shared.so file under the build/lib path. However, I noticed that the parent library module copies the libc++_shared.so file under jni/armeabi-v7a/libc++_shared.so inside the build/exploded-aar directory structure. (See above) Should the closure instead read exclude 'jni/armeabi-v7a/libc++_shared.so (i.e. jni vs. lib)?
Since I am using Gradle plugin 0.9.1, I tried using pickFirst in place of exclude, but that wasn't successful either.
Can someone help determine how I should configure the `packagingOptions' closure for my given case?
Thank you for your help!
I ran into the same problem and had no luck with exclude or pickFirst. So I used a somewhat ugly workaround. The idea is to create a 'native-libs' folder in the build directory of the main project, copy all required *.so files from ndk library projects there and then tell the build system to package those libs in the apk.
In my main project (the app project), I explicitely define the list of modules that contain ndk codes on which I depend
// Ndk stuff. We have to explicitely manage our NDK dependencies
ext.jniProjects = [project(':ndklib1'), project(':ndklib2'), project(':ndklib3')]
apply from: '../depend_ndk.gradle'
And then, 'depend_ndk.gradle' is a gradle external script that contains
// Build helper for projects that depends on a native library with a NDK part
// Define the list of ndk library you depend on in project main file :
// ext.jniProjects = [project(':ndklib1')]
// apply from : 'depend_ndk.gradle'
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.12.+'
}
}
import com.android.build.gradle.tasks.PackageApplication
// As a workaround, we create a new 'native-libs' folder in the current project and
// copy all the .so we depend on into it
def ndkLibsDir = new File(buildDir, 'native-libs')
ndkLibsDir.mkdir()
task copyDependingNativeLibs(type: Copy) {
// Doc for copy http://www.gradle.org/docs/current/dsl/org.gradle.api.tasks.Copy.html
println 'jniProjects ' + jniProjects
jniProjects.each {
from(new File(it.buildDir, 'native-libs')) {
include '**/*.so'
}
}
into ndkLibsDir
}
tasks.withType(PackageApplication) { pkgTask ->
pkgTask.jniFolders = new HashSet<File>()
pkgTask.jniFolders.add(ndkLibsDir)
pkgTask.dependsOn copyDependingNativeLibs
}