META-INF/versions/9/module-info.class: broken class file? (This feature requires ASM6)
Solution 1
There is a more simple workaround. Basically the problem can be identified as "running Gradle with Java 8, while handling files which were built with Java 9". My new approach is building with Java 11 (GitHub Actions also builds with Java 11 and Gradle 6.7.1 would currently support up to Java 15).
-
After installing Java 11 with
sudo dnf install java-11-openjdk
-
alternatives --display java
will list the JDK to use.
For example: /usr/lib/jvm/java-11-openjdk-11.0.11.0.9-0.el8_3.x86_64
:
On a side note, building with JDK 11 also fixes this warning:
Current JDK version 1.8.0_172-b11 has a bug (https://bugs.openjdk.java.net/browse/JDK-8007720) that prevents Room from being incremental. Consider using JDK 11+ or the embedded JDK shipped with Android Studio 3.5+.
The "embedded JDK shipped with Android Studio 3.5+" is still Java 8 ...
Solution 2
As already mentioned this was introduced in Java 9, that Android does not support. You could just use packagingOptions
to remove those classes.
android {
packagingOptions {
exclude "**/module-info.class"
}
}
This should not affect actual executed code and should also remove classes for lint checks as lint is working on bytecode.
Solution 3
Update: Please see my current answer, which nails the problem.
This answer is only being kept as an example for Gradle scripting.
When using old versions (likely built with Java 8), there are no such processing errors:
// https://mvnrepository.com/artifact/org.bouncycastle
implementation "org.bouncycastle:bcprov-jdk15on:1.60"
implementation "org.bouncycastle:bcpkix-jdk15on:1.60"
// https://mvnrepository.com/artifact/com.google.code.gson/gson
implementation "com.google.code.gson:gson:2.8.5"
The issue obviously was introduced with version 1.61
/ 2.8.6
(likely built with Java 9).
It's annoying when Google brings one back to the own answer, which is not really an answer. Instead of keeping back the version or editing the JAR, I've wrote a DeleteModuleInfoTask
and a shell script, which automates the deletion of module-info.class
from any given Java dependency.
Since commandLine
only accepts a single command, one almost has to call a script. And this should serve as a good example for a custom Exec
task.
For Linux: module_info.sh
considers versions/9/module-info.class
and module-info.class
:
#!/usr/bin/env bash
GRADLE_CACHE_DIR=$HOME/.gradle/caches/modules-2/files-2.1
ZIP_PATHS=(META-INF/versions/9/module-info.class module-info.class)
if [[ $# -ne 3 ]]; then
echo "Illegal number of parameters"
exit 1
else
if [ -d "$GRADLE_CACHE_DIR" ]; then
DIRNAME=${GRADLE_CACHE_DIR}/$1/$2/$3
if [ -d "$DIRNAME" ]; then
cd ${DIRNAME} || exit 1
find . -name ${2}-${3}.jar | (
read ITEM;
for ZIP_PATH in "${ZIP_PATHS[@]}"; do
INFO=$(zipinfo ${ITEM} ${ZIP_PATH} 2>&1)
if [ "${INFO}" != "caution: filename not matched: ${ZIP_PATH}" ]; then
zip ${ITEM} -d ${ZIP_PATH} # > /dev/null 2>&1
fi
done
)
exit 0
fi
fi
fi
For Windows: module_info.bat
depends on 7-Zip:
@echo off
REM delete module.info from JAR file - may interfere with the local IDE.
for /R %USERPROFILE%\.gradle\caches\modules-2\files-2.1\%1\%2\%3\ %%G in (%2-%3.jar) do (
if exist %%G (
7z d %%G META-INF\versions\9\module-info.class > NUL:
7z d %%G versions\9\module-info.class > NUL:
7z d %%G module-info.class > NUL:
)
)
Update: After some testing I came to the conclusion that it may be better to manually edit the file when developing on Windows, because Android Studio and Java will lock the JAR, which will subsequently prevent the edit and leave the temp file behind.
File tasks.gradle
provides the DeleteModuleInfoTask
:
import javax.inject.Inject
abstract class DeleteModuleInfoTask extends Exec {
@Inject
DeleteModuleInfoTask(String dependency) {
def os = org.gradle.internal.os.OperatingSystem.current()
def stdout = new ByteArrayOutputStream()
def stderr = new ByteArrayOutputStream()
ignoreExitValue true
standardOutput stdout
errorOutput stderr
workingDir "${getProject().getGradle().getGradleUserHomeDir()}${File.separator}caches${File.separator}modules-2${File.separator}files-2.1${File.separator}${dependency.replace(":", File.separator).toString()}"
String script = "${getProject().getRootDir().getAbsolutePath()}${File.separator}scripts${File.separator}"
def prefix = ""; def suffix = "sh"
if (os.isWindows()) {prefix = "cmd /c "; suffix = "bat"}
String[] item = dependency.split(":")
commandLine "${prefix}${script}module_info.${suffix} ${item[0]} ${item[1]} ${item[2]}".split(" ")
// doFirst {println "${commandLine}"}
doLast {
if (execResult.getExitValue() == 0) {
if (stdout.toString() != "") {
println "> Task :${project.name}:${name} ${stdout.toString()}"
}
} else {
println "> Task :${project.name}:${name} ${stderr.toString()}"
}
}
}
}
Example Usage:
// Bouncycastle
tasks.register("lintFixModuleInfoBcPkix", DeleteModuleInfoTask, "org.bouncycastle:bcpkix-jdk15on:1.64")
lint.dependsOn lintFixModuleInfoBcPkix
tasks.register("lintFixModuleInfoBcProv", DeleteModuleInfoTask, "org.bouncycastle:bcprov-jdk15on:1.64")
lint.dependsOn lintFixModuleInfoBcProv
// GSON
tasks.register("lintFixModuleInfoGson", DeleteModuleInfoTask, "com.google.code.gson:gson:2.8.6")
lint.dependsOn lintFixModuleInfoGson
// Kotlin Standard Library
tasks.register("lintFixModuleInfoKotlinStdLib", DeleteModuleInfoTask, "org.jetbrains.kotlin:kotlin-stdlib:1.4.32")
lint.dependsOn lintFixModuleInfoKotlinStdLib
Make sure to register these tasks only for a single module.
According to resmon
"Resource Monitor" > "Associated Handles", studio64
and java
may hold a lock on the JAR file, therefore 7-Zip may only be able to edit the archive when Android Studio and Java had been closed; at least it nicely works for CI on Linux.
Solution 4
The file module-info.class
is part of the Java module system which was introduced since Java 9. As per this issue on Android IssueTracker, the bug has been be fixed since Android Studio 3.4.
Solution 5
I have got the following error message:
Error processing C:\Users\mypc\.gradle\caches\modules-2\files-2.1\com.google.code.gson\gson\2.8.6\9180733b7df8542621dc12e21e87557e8c99b8cb\gson-2.8.6.jar:module-info.class: broken class file? (This feature requires ASM6)
This error occurs without using a development system like Android Studio. I use Gradle 6.1.1.
I prevented the mistake as follows:
- Open the file
gson-2.8.6.jar
which is named in the error message - Removing of the file
module-info.class
, which is located in the root
Related videos on Youtube
Martin Zeitler
I'm usually available for hire on PPH. Favorite Cartoon: Are You Lost in the World Like Me? (Animated Short Film by Steve Cutts) Open Source Projects: Android Image Builder for Google Cloud Build & Cloud KMS Google Cloud Functions - PHP Quickstart PHP SDK for Huawei REST API Android GitHub API Client
Updated on June 04, 2022Comments
-
Martin Zeitler almost 2 years
I'm having issues with Bouncycastle, which only arise when running the
:lint
task.Generally it seems to be a Java 9 byte-code version 53.0 / ASM version conflict.
These are the dependencies:
// https://mvnrepository.com/artifact/org.bouncycastle implementation "org.bouncycastle:bcprov-jdk15on:1.64" implementation "org.bouncycastle:bcpkix-jdk15on:1.64"
Which cause the
:lint
task to throw processing errors:> Task :mobile:lint Error processing bcpkix-jdk15on-1.64.jar:META-INF/versions/9/module-info.class: broken class file? (This feature requires ASM6) Error processing bcprov-jdk15on-1.64.jar:META-INF/versions/9/module-info.class: broken class file? (This feature requires ASM6)
META-INF/versions/9/module-info.class: broken class file? (This feature requires ASM6)
The same goes for:
// https://mvnrepository.com/artifact/com.google.code.gson/gson implementation "com.google.code.gson:gson:2.8.6"
Since upgrading from
1.4.1
to1.4.2-native-mt
, it's the same again:implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2-native-mt"
kotlin-stdlib-1.4.0.jar:META-INF\versions\9\module-info.class: broken class file? (Module requires ASM6)
-
Martin Zeitler about 4 yearsHave already tried that before asking (in all possible variations), it's not working... because the packaging obviously happens after the processing.
-
Evgenii Vorobei about 4 yearsWhat about plain command line Gradle? We don't use Android Studio on CI server.
-
Martin Zeitler over 3 yearsEditing cached files is not reliable; this should be automated.
-
Martin Zeitler about 3 years@EvgeniiVorobei See my updated answer, I've wrote a task which can accomplish that.
-
moster67 about 3 yearsHow would I execute this (I am on Windows)? Do I create the various files in for instance notepad++? If yes, where do I save them? Do I run them from Terminal in Android Studio? Sorry for my ignorance.
-
Martin Zeitler about 3 yearsAndroid Studio was used as editor. The Gradle task is platform-independent - for Windows you'd need
module_info.bat
and 7-Zip. When building remotely,module_info.sh
still may be required.