Android Gradle Build: duplicate entry: META-INF/app_release.kotlin_module - android

I'm trying to build a release app via Android Studio > Generate Signed Bundle or APK > Android App Bundle > Release
However gradle fails with
: > Task :core:transformClassesWithMergeClassesForRelease FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':core:transformClassesWithMergeClassesForRelease'.
> 1 exception was raised by workers:
java.util.zip.ZipException: duplicate entry: META-INF/app_release.kotlin_module
In my build.gradle I've tried adding:
packagingOptions {
exclude 'META-INF/app_release.kotlin_module'
}
But it isn't making any difference whatsoever.
How do I fix this?
For extra context, it's a multi module project.
I have a core module, and an installed module which is declared in the core build.gradle with dynamicFeatures = [":installed"]
Thanks

Please make sure all your dependencies are api or implementation,
I have the flowing dependency grap.
meemo_sdk:
api project(":gvoice")
app project:
implementation project(":gvoice")
implementation project("meemo_sdk")
It complains "META-INF/gvoice_debug.kotlin_module" collision.
After change api to implementation, it works!

So I figured it out.
I pressed shift twice in Android studio (to open up the search everywhere dialog) and searched for app_release.kotlin_module
I saw two files, that were under two of my dependencies (which funnily enough were libraries that I had created!)
I opened up these library projects, and in the build.gradle file I had to add:
ext {
PUBLISH_GROUP_ID = 'com.companyname'
PUBLISH_ARTIFACT_ID = 'packagename'
}
android {
...
compileOptions {
kotlinOptions.freeCompilerArgs += ['-module-name', "$PUBLISH_GROUP_ID.$PUBLISH_ARTIFACT_ID"]
}
}
Rebuilt the library projects with new versions, used these new versions in my other project, and it started compiling :)

Build -> Clean Project Worked for me

I found the same issue comes randomly by using Android Studio 4.2.1 and Java8, I sorted out successfully by deleting .gradle file in the project (not the main one) every time I get the error.
Java version: JDK8221
Kotlin: 1.5.0
AndroidStudio: 4.2.1
Not the best solution but is a good workaround for now.

Related

How to make android-app-module identify and use gradle-plugin-module sources

I've created a standalone plugin along with a simple demo app, that I need for development. Both are added to the same project as an app-module and a plugin-module, so that I can easily develop and test features I write in the plugin. I'm assuming that if I add the sources from the plugin to buildSrc/build.gradle.kts, I'll be able to reference the plugin sources from the app (I need that to build and apply the plugin). The demo project in its entirety can be found here: https://github.com/oizo/gradle-plugin-sample.
Currently, it seems that when I apply the plugin in app/build.gradle.kts it's available (autocomplete is working) but when I try to build with ./gradlew build it fails with this message:
FAILURE: Build failed with an exception.
* Where:
Build file '/Users/MyUser/github/gradle-plugin-sample/app/build.gradle.kts' line: 10
* What went wrong:
Script compilation error:
Line 10: apply<io.hvam.android.plugin.StringPlugin>()
^ Unresolved reference: io
Clearly, I'm missing something.
I've tried the solution proposed in this post-https://stackoverflow.com/a/42263532/1181023, which seems to be a similar problem, but when I run ./gradlew build --include-build plugin/ it also fails to build, with the following:
FAILURE: Build failed with an exception.
* What went wrong:
Included build in /Users/MyUser/github/gradle-plugin-sample/plugin has a root project whose name 'plugin' is the same as a project of the main build.
I see two issues:
Your plugin must be packaged in such a way that your Plugin implementing class is visible to consumers of the plugin as the entry point. One easy way of doing that is by using gradlePlugin {} block. I would recommend to upgrade to at least Gradle 5.5.1 and use build init plugin to automate all these for you.
Please try gradle init --type kotlin-gradle-plugin to generate the plugin project. This would add code similar to below in your plugin build.gradle which ensures your consumers can apply the plugin using apply plugin: "stringPlugin".
gradlePlugin {
plugins {
stringPlugin {
id = "stringPlugin"
implementationClass = "com.example.StringPlugin"
}
}
}
Secondly, your plugin must be visible to the buildscript classpath so that it can apply your plugin. If you have already published the plugin to maven, then you can add the below in project level build.gradle to let gradle discover your plugin.
buildscript {
...
dependencies {
classpath "com.example:stringplugin"
}
}
Publishing to maven might not be convenient during development. You could utilize Gradle's composite builds to help in this regard. In your project level settings.gradle, add below:
includeBuild('./plugin') {
dependencySubstitution {
substitute module('com.example:stringplugin') with project(':plugin')
}
}
This instructs gradle to use locally present :plugin module when com.example:stringplugin is requested. This would be convenient for development.
It seems I misunderstood how gradle uses the buildSrc folder. I've moved the content of buildscript into buildSrc/build.gradle.kts but omitting the actual buildscript extension. This somehow fixed the issue of the app-module not being able to recognize the plugin sources when building. The specific changes related to the fix can be reviewed int this commit. And the sample code in the repo now builds as expected.
This gives some more clarity about the purpose of the buildSrc folder: https://stackoverflow.com/a/13875350/1181023

Android Studio 3.0 RC1 error when adding androidTest package after removal

Prieviously in my project i deleted my androidTest package as i didn't use this.
Now i manually add this package to my project.
So i have src/androidTest/java/domain/name/myTestclass.kt
After i try to build the project i get an error:
Error:Execution failed for task ':location:transformResourcesWithMergeJavaResForDebugAndroidTest'.
More than one file was found with OS independent path 'protobuf.meta'
What is the cause and how to solve this?
I am using Android Studio 3.0 RC1
I have the same problem when running androidTest, and it seems to be a conflict between espresso and playservices-location on my end. I added in my gradle file :
packagingOptions {
pickFirst 'protobuf.meta'
}
Seems to be enough for me because I'm not using playservices-location in my tests, but I'm not sure this is a correct solution.

"Could not initialize class" error running lint target from gradle

I'm working on an Android project with two projects inside it. When trying to run a build with gradlew (./gradlew build), I see the following error:
Execution failed for task ':example:lint'.
Could not initialize class
com.android.build.gradle.tasks.Lint$LintGradleIssueRegistry
With stacktrace enabled, this is listed as a java.lang.NoClassDefFoundError.
Oddly, the first time I ran this (which downloaded dependencies), the build failed with a different error:
Execution failed for task ':example:lint'.
lombok/ast/Node
The gradle wrapper that Android SDK created for the project is using Gradle 2.8.
Could this be a configuration issue with the project or my dev machine? I'm trying to avoid using the Android SDK lint tool as this complains about the projects using Gradle (and I hear it may miss some parts of these projects).
Turned out this was a configuration issue in our build.gradle. The following line had been added for testing and never removed:
configurations.classpath.exclude group: 'com.android.tools.external.lombok'
As such, the classes needed for linting were missing.
The following discussion pointed us in the right direction, in case it's useful to anyone else:
https://github.com/evant/gradle-retrolambda/issues/96

Android: Skip Gradle "testClasses" task for a dependency project

I have followed this guide to create a JUnit test file for my main Android module (let's call it "module-a"), in Android Studio v1.4.
My "module-a" has a dependency on an external library that is provided as a .aar file and for which I had to create a dedicated module.
This dependency causes an error:
When right clicking the test Java file and hitting "Run MyTestName" , it fails with this error
Error:Gradle:
FAILURE: Build failed with an exception.
* What went wrong:
Task 'testClasses' not found in project ':module-b'.
Removing the dependency on module-b solves the problem.
Excerpt of module-a build.gradle:
compile project(':module-b')
module-b build.gradle:
configurations.create("default")
artifacts.add("default", file('library-b.aar'))
How should I configure Gradle so that it does not try to run the testClasses task on "module-b" ? (this should solve my issue)
I did not find a way to skip the testClasses task for module-b: it seems that actions started from Android Studio (like running a JUnit test) run Gradle commands that cannot be modified. In my case:
Information:Gradle: Executing tasks:
[:module-a:prepareFree_flavorDebugUnitTestDependencies,
:module-a:generateFree_flavorDebugSources,
:module-a:mockableAndroidJar,
:module-a:assembleFree_flavorDebug,
:module-a:assembleFree_flavorDebugUnitTest,
:module-b:testClasses]
I found a workaround for my problem, though:
Add the following code to module-b build.gradle:
task testClasses {
doLast {
println 'This is a dummy testClasses task'
}
}

Gradle: Only resolve dependencies for the desired variant

I have a test app with three flavors:
dev: Uses a local copy of the library during development
qa: Uses a snapshot during QA
rc: Uses a prerelease build for release candidate testing.
dependencies {
devCompile project(':library')
qaCompile 'com.example:library:1.0.0-SNAPSHOT#aar'
rcCompile 'com.example:library:1.0.0#aar'
}
I run Gradle, and expect it to do the minimum amount of work necessary to build just what I want:
./gradlew :test-app:connectedAndroidTestDevDebug
However, the build fails, because it is trying to resolve dependencies for all build flavors, not just the one I am building.
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':test-app'.
Could not resolve all dependencies for configuration ':test-app:_qaDebugCompile'.
Could not find com.example:library1.0.0-SNAPSHOT.
Searched in the following locations:
https://repo1.maven.org/maven2/com/example/library/1.0.0-SNAPSHOT/maven-metadata.xml
https://repo1.maven.org/maven2/com/example/library/1.0.0-SNAPSHOT/library-1.0.0-SNAPSHOT.pom
https://repo1.maven.org/maven2/com/example/library/1.0.0-SNAPSHOT/library-1.0.0-SNAPSHOT.aar
http://oss.sonatype.org/content/repositories/snapshots/com/example/library/1.0.0-SNAPSHOT/maven-metadata.xml
http://oss.sonatype.org/content/repositories/snapshots/com/example/library/1.0.0-SNAPSHOT/library-1.0.0-SNAPSHOT.pom
http://oss.sonatype.org/content/repositories/snapshots/com/example/library/1.0.0-SNAPSHOT/library-1.0.0-SNAPSHOT.aar
file:/opt/android-sdk-macosx/extras/android/m2repository/com/example/library/1.0.0-SNAPSHOT/maven-metadata.xml
file:/opt/android-sdk-macosx/extras/android/m2repository/com/example/library/1.0.0-SNAPSHOT/library-1.0.0-SNAPSHOT.pom
file:/opt/android-sdk-macosx/extras/android/m2repository/com/example/library/1.0.0-SNAPSHOT/library-1.0.0-SNAPSHOT.aar
file:/opt/android-sdk-macosx/extras/google/m2repository/com/example/library/1.0.0-SNAPSHOT/maven-metadata.xml
file:/opt/android-sdk-macosx/extras/google/m2repository/com/example/library/1.0.0-SNAPSHOT/library-1.0.0-SNAPSHOT.pom
file:/opt/android-sdk-macosx/extras/google/m2repository/com/example/library/1.0.0-SNAPSHOT/library-1.0.0-SNAPSHOT.aar
Required by:
project-name:test-app:unspecified
The SNAPSHOT that the qa flavor is trying to resolve doesn't exist yet, and that should be fine, because I'm not trying to build the qa flavor. If that SNAPSHOT build is present, then everything works fine.
Questions:
Why are all build flavors having their dependencies resolved?
How can I accomplish building just one flavor without encountering this problem?
Is there some better way to do this that will be more "Gradley"?
I assume that the build works if you exclude the task manually?
gradle connectedAndroidTestDevDebug -x _qaDebugCompile
It looks like the task connectedAndroidTestDevDebug has a dependency on the task _qaDebugCompile, which causes your problem. I don't know how your tasks are defined, but you can study your dependencies using Gradle's built-in tasks gradle dependencies and gradle dependencyInsight. Maybe that will give you a hint in the right direction:
gradle dependencyInsight --dependency com.example:library:1.0.0-SNAPSHOT
You can read more about task dependencies in the gradle User's guide.
I finally solved this by checking the list of tasks and if there is a task for the desired build variant, adding the dependency.
dependencies {
gradle.startParameter.taskRequests.each { taskRequest ->
taskRequest.args.each { taskName ->
String flavorName = "qa";
if (taskName.toLowerCase().endsWith(flavorName+"debug") ||
taskName.toLowerCase().endsWith(flavorName+"release")) {
qaCompile 'com.example:my-library:1.0.0-SNAPSHOT#aar'
}
}
}
devCompile project(':localLibrary')
//qaCompile 'com.example:my-library:1.0.0-SNAPSHOT#aar' // What I used to do.
rcCompile 'com.example:my-library:1.0.0#aar'
}
Keep in mind that the task list will not contain dependent task names, so if you aren't invoking a task that contains your build flavor name, it won't work. This is just something I got working.

Categories

Resources