Document problems with building coroutines-using Android projects (#2288)

Added instructions to work around #2023 
Also, the answer to #2274 is now documented.

Co-authored-by: Vsevolod Tolstopyatov <qwwdfsad@gmail.com>
diff --git a/README.md b/README.md
index 4b6f99b..7f71d28 100644
--- a/README.md
+++ b/README.md
@@ -176,6 +176,17 @@
 R8 and ProGuard rules are bundled into the [`kotlinx-coroutines-android`](ui/kotlinx-coroutines-android) module.
 For more details see ["Optimization" section for Android](ui/kotlinx-coroutines-android/README.md#optimization). 
 
+#### Avoiding including the debug infrastructure in the resulting APK
+
+The `kotlinx-coroutines-core` artifact contains a resource file that is not required for the coroutines to operate
+normally and is only used by the debugger. To exclude it at no loss of functionality, add the following snippet to the
+`android` block in your gradle file for the application subproject:
+```groovy
+packagingOptions {
+  exclude "DebugProbesKt.bin"
+}
+```
+
 ### JS
 
 [Kotlin/JS](https://kotlinlang.org/docs/reference/js-overview.html) version of `kotlinx.coroutines` is published as 
diff --git a/kotlinx-coroutines-debug/README.md b/kotlinx-coroutines-debug/README.md
index 7c4501a..1278ed1 100644
--- a/kotlinx-coroutines-debug/README.md
+++ b/kotlinx-coroutines-debug/README.md
@@ -170,6 +170,98 @@
         at kotlinx.coroutines.debug.DebugProbes.install(DebugProbes.kt:49)
 -->
 
+#### Build failures due to duplicate resource files
+
+Building an Android project that depends on `kotlinx-coroutines-debug` (usually introduced by being a transitive
+dependency of `kotlinx-coroutines-test`) may fail with `DuplicateRelativeFileException` for `META-INF/AL2.0`,
+`META-INF/LGPL2.1`, or `win32-x86/attach_hotspot_windows.dll` when trying to merge the Android resource.
+
+The problem is that Android merges the resources of all its dependencies into a single directory and complains about
+conflicts, but:
+* `kotlinx-coroutines-debug` transitively depends on JNA and JNA-platform, both of which include license files in their
+  META-INF directories. Trying to merge these files leads to conflicts, which means that any Android project that
+  depends on JNA and JNA-platform will experience build failures.
+* Additionally, `kotlinx-coroutines-debug` embeds `byte-buddy-agent` and `byte-buddy`, along with their resource files.
+  Then, if the project separately depends on `byte-buddy`, merging the resources of `kotlinx-coroutines-debug` with ones
+  from `byte-buddy` and `byte-buddy-agent` will lead to conflicts as the resource files are duplicated.
+
+One possible workaround for these issues is to add the following to the `android` block in your gradle file for the
+application subproject:
+```groovy
+     packagingOptions {
+         // for JNA and JNA-platform
+         exclude "META-INF/AL2.0"
+         exclude "META-INF/LGPL2.1"
+         // for byte-buddy
+         exclude "META-INF/licenses/ASM"
+         pickFirst "win32-x86-64/attach_hotspot_windows.dll"
+         pickFirst "win32-x86/attach_hotspot_windows.dll"
+     }
+```
+This will cause the resource merge algorithm to exclude the problematic license files altogether and only leave a single
+copy of the files needed for `byte-buddy-agent` to work.
+
+Alternatively, avoid depending on `kotlinx-coroutines-debug`. In particular, if the only reason why this library a
+dependency of your project is that `kotlinx-coroutines-test` in turn depends on it, you may change your dependency on
+`kotlinx.coroutines.test` to exclude `kotlinx-coroutines-debug`. For example, you could replace
+```kotlin
+androidTestImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version")
+```
+with
+```groovy
+androidTestImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version") {
+    exclude group: "org.jetbrains.kotlinx", module: "kotlinx-coroutines-debug"
+}
+```
+<!---
+Snippets of stacktraces for googling:
+
+org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:mergeDebugAndroidTestJavaResource'.
+        ...
+Caused by: org.gradle.workers.intelrnal.DefaultWorkerExecutor$WorkExecutionException: A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
+        ...
+Caused by: com.android.builder.merge.DuplicateRelativeFileException: More than one file was found with OS independent path 'META-INF/AL2.0'.
+        at com.android.builder.merge.StreamMergeAlgorithms.lambda$acceptOnlyOne$2(StreamMergeAlgorithms.java:85)
+        at com.android.builder.merge.StreamMergeAlgorithms.lambda$select$3(StreamMergeAlgorithms.java:106)
+        at com.android.builder.merge.IncrementalFileMergerOutputs$1.create(IncrementalFileMergerOutputs.java:88)
+        at com.android.builder.merge.DelegateIncrementalFileMergerOutput.create(DelegateIncrementalFileMergerOutput.java:64)
+        at com.android.build.gradle.internal.tasks.MergeJavaResourcesDelegate$run$output$1.create(MergeJavaResourcesDelegate.kt:230)
+        at com.android.builder.merge.IncrementalFileMerger.updateChangedFile(IncrementalFileMerger.java:242)
+        at com.android.builder.merge.IncrementalFileMerger.mergeChangedInputs(IncrementalFileMerger.java:203)
+        at com.android.builder.merge.IncrementalFileMerger.merge(IncrementalFileMerger.java:80)
+        at com.android.build.gradle.internal.tasks.MergeJavaResourcesDelegate.run(MergeJavaResourcesDelegate.kt:276)
+        at com.android.build.gradle.internal.tasks.MergeJavaResRunnable.run(MergeJavaResRunnable.kt:81)
+        at com.android.build.gradle.internal.tasks.Workers$ActionFacade.run(Workers.kt:242)
+        at org.gradle.workers.internal.AdapterWorkAction.execute(AdapterWorkAction.java:50)
+        at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:50)
+        at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:63)
+        at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:59)
+        at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:98)
+        at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:59)
+        at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
+        at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
+        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
+        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
+        at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
+        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
+        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
+        at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
+        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
+        at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
+        at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:53)
+        at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$2(DefaultWorkerExecutor.java:200)
+        at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:215)
+        at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
+        at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:131)
+
+Execution failed for task ':app:mergeStagingDebugAndroidTestJavaResource'.
+Execution failed for task ':app:mergeDebugAndroidTestJavaResource'.
+Execution failed for task ':app:mergeDebugTestJavaResource'
+
+More than one file was found with OS independent path 'META-INF/LGPL2.1'
+More than one file was found with OS independent path 'win32-x86/attach_hotspot_windows.dll'
+More than one file was found with OS independent path 'win32-x86-64/attach_hotspot_windows.dll'
+-->
 <!--- MODULE kotlinx-coroutines-core -->
 <!--- INDEX kotlinx.coroutines -->
 [Job]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/index.html