Обновление: см. мой текущий ответ, который решает проблему.
Этот ответ хранится только в качестве примера для сценариев Gradle.
При использовании старых версий (вероятно, построенных с Java 8) таких ошибок обработки нет:
// 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"
Проблема, очевидно, возникла в версии 1.61
/2.8.6
(вероятно, построенной на Java 9).
Это раздражает, когда Google возвращает человека к собственному ответу, который на самом деле не является ответом. Вместо того, чтобы сохранять версию или редактировать JAR, я написал DeleteModuleInfoTask
и сценарий оболочки, который автоматизирует удаление module-info.class
из любой заданной зависимости Java.
Поскольку commandLine
принимает только одну команду, почти приходится вызывать скрипт. И это должно послужить хорошим примером для пользовательской задачи Exec
.
Для Linux: module_info.sh
учитывает versions/9/module-info.class
и 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
Для Windows: module_info.bat
зависит от 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:
)
)
Обновление: после некоторого тестирования я пришел к выводу, что может быть лучше вручную отредактировать файл при разработке в Windows, потому что Android Studio и Java заблокируют JAR, что впоследствии предотвратит редактирование и оставит временный файл позади.
Файл tasks.gradle
содержит 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()}"
}
}
}
}
Пример использования:
// 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
Обязательно зарегистрируйте эти задачи только для одного модуля.
Согласно resmon
Resource Monitor › Associated Handles, studio64
и java
могут блокировать файл JAR, поэтому 7-Zip может редактировать архив только тогда, когда Android Studio и Java закрыты; по крайней мере, это хорошо работает для CI в Linux.
person
Martin Zeitler
schedule
12.03.2020