nilkash
nilkash

Reputation: 7536

Dynamic feature release build failed with duplicate resources

I am creating one sample to check dynamic feature delivery provided by android. I have project structure in following way. Base project app and one dynamic feature sample_dynamic_feature. All the setup required for dynamic feature delivery is in place. The problem comes when I add any layout file or .xml file with same name in base module as well as in dynamic module. I added activity_main.xml in both base application as well as in dynamic module. I got the following error :

What went wrong:

Execution failed for task ':app:packageReleaseBundle'.
> java.util.concurrent.ExecutionException: com.android.tools.build.bundletool.exceptions.ValidationException: com.android.tools.build.bundletool.exceptions.ValidationException: Modules 'base' and 'sample_dynamic_feature' contain entry 'res/layout/activity_main.xml' with different content.

Works fine with :

Above setup works fine in debug mode.
./gradlew assembleDebug
./gradlew assembleRelease

Failing with:

In case of release mode it gives me above error.
./gradlew bundleDebug
./gradlew bundleRelease

Full stack-trace:

Exception is: org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:packageReleaseBundle'. at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:110) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:77) at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51) at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:59) at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54) at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:59) at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:101) at org.gradle.api.internal.tasks.execution.FinalizeInputFilePropertiesTaskExecuter.execute(FinalizeInputFilePropertiesTaskExecuter.java:44) at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:91) at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:62) at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:59) at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54) at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43) at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.run(EventFiringTaskExecuter.java:51) at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300) at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292) at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174) at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90) at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31) at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:46) at org.gradle.execution.taskgraph.LocalTaskInfoExecutor.execute(LocalTaskInfoExecutor.java:42) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareWorkItemExecutor.execute(DefaultTaskExecutionGraph.java:277) at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareWorkItemExecutor.execute(DefaultTaskExecutionGraph.java:262) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:135) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:130) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker.execute(DefaultTaskPlanExecutor.java:200) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker.executeWithWork(DefaultTaskPlanExecutor.java:191) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker.run(DefaultTaskPlanExecutor.java:130) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63) at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46) at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55) Caused by: org.gradle.internal.UncheckedException: java.util.concurrent.ExecutionException: com.android.tools.build.bundletool.exceptions.ValidationException: Modules 'base' and 'sample_dynamic_feature' contain entry 'res/layout/activity_main.xml' with different content. at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:63) at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:40) at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:76) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:46) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26) at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:801) at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:768) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:131) at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300) at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292) at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174) at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90) at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:120) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:99) ... 31 more Caused by: java.util.concurrent.ExecutionException: com.android.tools.build.bundletool.exceptions.ValidationException: Modules 'base' and 'sample_dynamic_feature' contain entry 'res/layout/activity_main.xml' with different content. at com.android.ide.common.workers.ExecutorServiceAdapter.close(ExecutorServiceAdapter.kt:56) at kotlin.io.CloseableKt.closeFinally(Closeable.kt:53) at com.android.build.gradle.internal.tasks.PackageBundleTask.bundleModules(PackageBundleTask.kt:121) at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73) ... 44 more Caused by: com.android.tools.build.bundletool.exceptions.ValidationException: Modules 'base' and 'sample_dynamic_feature' contain entry 'res/layout/activity_main.xml' with different content. at com.android.tools.build.bundletool.exceptions.ValidationException$Builder.build(ValidationException.java:49) at com.android.tools.build.bundletool.exceptions.ValidationException$Builder.build(ValidationException.java:41) at com.android.tools.build.bundletool.validation.EntryClashValidator.checkEqualEntries(EntryClashValidator.java:66) at com.android.tools.build.bundletool.validation.EntryClashValidator.validateAllModules(EntryClashValidator.java:52) at com.android.tools.build.bundletool.validation.ValidatorRunner.validateBundleModulesUsingSubValidator(ValidatorRunner.java:75) at com.android.tools.build.bundletool.validation.ValidatorRunner.lambda$validateBundleModules$4(ValidatorRunner.java:64) at com.google.common.collect.ImmutableList.forEach(ImmutableList.java:407) at com.android.tools.build.bundletool.validation.ValidatorRunner.validateBundleModules(ValidatorRunner.java:63) at com.android.tools.build.bundletool.validation.BundleModulesValidator.validate(BundleModulesValidator.java:101) at com.android.tools.build.bundletool.commands.BuildBundleCommand.validateInput(BuildBundleCommand.java:244) at com.android.tools.build.bundletool.commands.BuildBundleCommand.execute(BuildBundleCommand.java:162) at com.android.build.gradle.internal.tasks.PackageBundleTask$BundleToolRunnable.run(PackageBundleTask.kt:200) at com.android.ide.common.workers.ExecutorServiceAdapter$submit$submission$1.run(ExecutorServiceAdapter.kt:39) ... 48 more

What does this bundle makes difference?

Upvotes: 3

Views: 2126

Answers (1)

Dinesh
Dinesh

Reputation: 988

While generating an APK using assembleRelease or assembleDebug, the build system generates different apk's for different dynamic features. One for base and one for each dynamic feature. So there is no resource conflict.

In case of generating app bundle, the build system would have conflict, since the artifact that is generated is one single artifact which is the aab file.

Upvotes: 1

Related Questions