gson 元INF/版本/9/模块信息类:损坏的类文件?(此功能需要ASM 6)

wmtdaxz3  于 2022-11-06  发布在  其他
关注(0)|答案(5)|浏览(237)

我在使用Bouncycastle时遇到了问题,这只在运行:lint任务时出现。
一般来说,这似乎是Java 9字节码版本53.0 /ASM版本冲突。
以下是相关性:

  1. // https://mvnrepository.com/artifact/org.bouncycastle
  2. implementation "org.bouncycastle:bcprov-jdk15on:1.64"
  3. implementation "org.bouncycastle:bcpkix-jdk15on:1.64"

这会导致:lint任务引发处理错误:

  1. > Task :mobile:lint
  2. Error processing bcpkix-jdk15on-1.64.jar:META-INF/versions/9/module-info.class: broken class file? (This feature requires ASM6)
  3. Error processing bcprov-jdk15on-1.64.jar:META-INF/versions/9/module-info.class: broken class file? (This feature requires ASM6)
  • 元INF/版本/9/模块信息类:损坏的类文件?(此功能需要ASM 6)*

这同样适用于:

  1. // https://mvnrepository.com/artifact/com.google.code.gson/gson
  2. implementation "com.google.code.gson:gson:2.8.6"

1.4.1升级到1.4.2-native-mt后,情况又是一样的:

  1. implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2-native-mt"

文件类型:损坏的类文件?(模块需要ASM 6)

nmpmafwu

nmpmafwu1#

如前所述,这是在Java 9中引入的,Android不支持。你可以只使用packagingOptions来删除这些类。

  1. android {
  2. packagingOptions {
  3. exclude "**/module-info.class"
  4. }
  5. }

这应该不会影响实际执行的代码,并且还应该删除用于lint检查的类,因为lint正在处理字节码。

slwdgvem

slwdgvem2#

更新:请查看我当前的answer,它解决了这个问题。

此答案仅作为Gradle脚本编写的示例保留。
使用旧版本(可能是使用Java 8构建的)时,不会出现此类处理错误:

  1. // https://mvnrepository.com/artifact/org.bouncycastle
  2. implementation "org.bouncycastle:bcprov-jdk15on:1.60"
  3. implementation "org.bouncycastle:bcpkix-jdk15on:1.60"
  4. // https://mvnrepository.com/artifact/com.google.code.gson/gson
  5. implementation "com.google.code.gson:gson:2.8.5"

这个问题显然是在版本1.61/2.8.6(可能是用Java 9构建的)中引入的。
当Google把一个人带回到自己的答案时,这是令人讨厌的,这并不是一个真正的答案。我没有保留版本或编辑JAR,而是编写了一个DeleteModuleInfoTask和一个shell脚本,它自动从任何给定的Java依赖项中删除module-info.class
由于commandLine只接受一个命令,因此几乎必须调用一个脚本。这应该是一个定制Exec任务的好例子。
对于Linux:module_info.sh考虑versions/9/module-info.classmodule-info.class

  1. # !/usr/bin/env bash
  2. GRADLE_CACHE_DIR=$HOME/.gradle/caches/modules-2/files-2.1
  3. ZIP_PATHS=(META-INF/versions/9/module-info.class module-info.class)
  4. if [[ $# -ne 3 ]]; then
  5. echo "Illegal number of parameters"
  6. exit 1
  7. else
  8. if [ -d "$GRADLE_CACHE_DIR" ]; then
  9. DIRNAME=${GRADLE_CACHE_DIR}/$1/$2/$3
  10. if [ -d "$DIRNAME" ]; then
  11. cd ${DIRNAME} || exit 1
  12. find . -name ${2}-${3}.jar | (
  13. read ITEM;
  14. for ZIP_PATH in "${ZIP_PATHS[@]}"; do
  15. INFO=$(zipinfo ${ITEM} ${ZIP_PATH} 2>&1)
  16. if [ "${INFO}" != "caution: filename not matched: ${ZIP_PATH}" ]; then
  17. zip ${ITEM} -d ${ZIP_PATH} # > /dev/null 2>&1
  18. fi
  19. done
  20. )
  21. exit 0
  22. fi
  23. fi
  24. fi

对于Windows:module_info.bat依赖于7-Zip

  1. @echo off
  2. REM delete module.info from JAR file - may interfere with the local IDE.
  3. for /R %USERPROFILE%\.gradle\caches\modules-2\files-2.1\%1\%2\%3\ %%G in (%2-%3.jar) do (
  4. if exist %%G (
  5. 7z d %%G META-INF\versions\9\module-info.class > NUL:
  6. 7z d %%G versions\9\module-info.class > NUL:
  7. 7z d %%G module-info.class > NUL:
  8. )
  9. )

更新:经过一些测试后,我得出结论,在Windows上开发时,手动编辑文件可能更好,因为Android Studio和Java会锁定JAR,这将随后阻止编辑并留下临时文件。
文件tasks.gradle提供了DeleteModuleInfoTask

  1. import javax.inject.Inject
  2. abstract class DeleteModuleInfoTask extends Exec {
  3. @Inject
  4. DeleteModuleInfoTask(String dependency) {
  5. def os = org.gradle.internal.os.OperatingSystem.current()
  6. def stdout = new ByteArrayOutputStream()
  7. def stderr = new ByteArrayOutputStream()
  8. ignoreExitValue true
  9. standardOutput stdout
  10. errorOutput stderr
  11. workingDir "${getProject().getGradle().getGradleUserHomeDir()}${File.separator}caches${File.separator}modules-2${File.separator}files-2.1${File.separator}${dependency.replace(":", File.separator).toString()}"
  12. String script = "${getProject().getRootDir().getAbsolutePath()}${File.separator}scripts${File.separator}"
  13. def prefix = ""; def suffix = "sh"
  14. if (os.isWindows()) {prefix = "cmd /c "; suffix = "bat"}
  15. String[] item = dependency.split(":")
  16. commandLine "${prefix}${script}module_info.${suffix} ${item[0]} ${item[1]} ${item[2]}".split(" ")
  17. // doFirst {println "${commandLine}"}
  18. doLast {
  19. if (execResult.getExitValue() == 0) {
  20. if (stdout.toString() != "") {
  21. println "> Task :${project.name}:${name} ${stdout.toString()}"
  22. }
  23. } else {
  24. println "> Task :${project.name}:${name} ${stderr.toString()}"
  25. }
  26. }
  27. }
  28. }

示例用法:

  1. // Bouncycastle
  2. tasks.register("lintFixModuleInfoBcPkix", DeleteModuleInfoTask, "org.bouncycastle:bcpkix-jdk15on:1.64")
  3. lint.dependsOn lintFixModuleInfoBcPkix
  4. tasks.register("lintFixModuleInfoBcProv", DeleteModuleInfoTask, "org.bouncycastle:bcprov-jdk15on:1.64")
  5. lint.dependsOn lintFixModuleInfoBcProv
  6. // GSON
  7. tasks.register("lintFixModuleInfoGson", DeleteModuleInfoTask, "com.google.code.gson:gson:2.8.6")
  8. lint.dependsOn lintFixModuleInfoGson
  9. // Kotlin Standard Library
  10. tasks.register("lintFixModuleInfoKotlinStdLib", DeleteModuleInfoTask, "org.jetbrains.kotlin:kotlin-stdlib:1.4.32")
  11. lint.dependsOn lintFixModuleInfoKotlinStdLib

请确保仅为单个模块注册这些任务。
根据resmon“资源监视器”〉“关联句柄”,studio64java可能持有JAR文件的锁,因此7-Zip可能只能在Android Studio和Java关闭时编辑存档;至少它可以很好地用于Linux上的CI。

展开查看全部
sg24os4d

sg24os4d3#

文件module-info.class是自Java 9以来引入的Java模块系统的一部分。根据Android IssueTracker上的this issue,该漏洞自Android Studio 3.4以来已得到修复。

hk8txs48

hk8txs484#

我收到以下错误消息:

  1. 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)

如果不使用Android Studio等开发系统,就会出现此错误。我使用的是Gradle 6.1.1。
我防止错误如下:
1.打开错误消息中命名的文件gson-2.8.6.jar
1.删除文件module-info.class,该文件位于根目录中

o2rvlv0m

o2rvlv0m5#

有一个更简单的解决方案。基本上,问题可以被确定为“使用Java 8运行Gradle,同时处理使用Java 9构建的文件”。我的新方法是使用Java 11构建(GitHub Actions也使用Java 11构建,Gradle 6.7.1目前最多支持Java 15)。

  • 使用sudo dnf install java-11-openjdk安装Java 11之后
  • alternatives --display java将列出要使用的JDK。

例如:/usr/lib/jvm/java-11-openjdk-11.0.11.0.9-0.el8_3.x86_64

顺便说一句,使用JDK 11进行构建还可以修复此警告:
当前JDK版本1.8.0_172-b11存在一个错误(https://bugs.openjdk.java.net/browse/JDK-8007720),阻止Room进行增量。请考虑使用JDK 11+或Android Studio 3.5+附带的嵌入式JDK。
“Android Studio 3.5+附带的嵌入式JDK”仍然是Java 8...

相关问题