Пользовательские правила linting не работают с com.android.tools.build:gradle:2.3.0
Моя команда и я разрабатываем приложения для Android и решили разработать правила кодирования, которые должны следовать всем. Поэтому я начал внедрять пользовательские правила lint, которые можно найти здесь, и добавили его в наш процесс автоматической сборки в Jenkins.
Проблема, с которой мы сейчас сталкиваемся, заключается в том, что эти правила больше не работают после обновления наших Android-проектов от
'com.android.tools.build:gradle:2.2.0'
до
'com.android.tools.build:gradle:2.3.0'
Мы постоянно получаем ошибку:
java.lang.NoSuchMethodError: com.android.tools.lint.detector.api.JavaContext.getContents()Ljava/lang/String;
При возврате к gradle 2.2.0
все в порядке, пользовательские правила проверяются и приложение создается.
Я попробовал обновление gradle в репозитории lint и, к сожалению, имел ту же самую проблему в моей TodoDetector в строке 72. В Android Studio все зависимости решены хорошо, но при попытке построить и развернуть библиотеку с помощью ./gradlew clean build test install
, мы получим ошибку, указанную выше.
Я искал весь день и еще не нашел жизнеспособного решения этой проблемы. Любая помощь, советы или советы приветствуются.
Выход терминала
:clean
:aarWrapper:clean
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:assemble
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test
:check
:build
:aarWrapper:preBuild UP-TO-DATE
:aarWrapper:preDebugBuild UP-TO-DATE
:aarWrapper:checkDebugManifest
:aarWrapper:prepareDebugDependencies
:aarWrapper:compileDebugAidl
:aarWrapper:compileDebugNdk UP-TO-DATE
:aarWrapper:compileLint
:aarWrapper:copyDebugLint UP-TO-DATE
:aarWrapper:mergeDebugShaders
:aarWrapper:compileDebugShaders
:aarWrapper:generateDebugAssets
:aarWrapper:mergeDebugAssets
:aarWrapper:mergeDebugProguardFiles UP-TO-DATE
:aarWrapper:packageDebugRenderscript UP-TO-DATE
:aarWrapper:compileDebugRenderscript
:aarWrapper:generateDebugResValues
:aarWrapper:generateDebugResources
:aarWrapper:packageDebugResources
:aarWrapper:processDebugManifest
:aarWrapper:generateDebugBuildConfig
:aarWrapper:processDebugResources
:aarWrapper:generateDebugSources
:aarWrapper:incrementalDebugJavaCompilationSafeguard
:aarWrapper:javaPreCompileDebug
:aarWrapper:compileDebugJavaWithJavac
:aarWrapper:processDebugJavaRes UP-TO-DATE
:aarWrapper:transformResourcesWithMergeJavaResForDebug
:aarWrapper:transformClassesAndResourcesWithSyncLibJarsForDebug
:aarWrapper:mergeDebugJniLibFolders
:aarWrapper:transformNativeLibsWithMergeJniLibsForDebug
:aarWrapper:transformNativeLibsWithStripDebugSymbolForDebug
:aarWrapper:transformNativeLibsWithSyncJniLibsForDebug
:aarWrapper:bundleDebug
:aarWrapper:compileDebugSources
:aarWrapper:assembleDebug
:aarWrapper:preReleaseBuild UP-TO-DATE
:aarWrapper:checkReleaseManifest
:aarWrapper:prepareReleaseDependencies
:aarWrapper:compileReleaseAidl
:aarWrapper:compileReleaseNdk UP-TO-DATE
:aarWrapper:copyReleaseLint UP-TO-DATE
:aarWrapper:mergeReleaseShaders
:aarWrapper:compileReleaseShaders
:aarWrapper:generateReleaseAssets
:aarWrapper:mergeReleaseAssets
:aarWrapper:mergeReleaseProguardFiles UP-TO-DATE
:aarWrapper:packageReleaseRenderscript UP-TO-DATE
:aarWrapper:compileReleaseRenderscript
:aarWrapper:generateReleaseResValues
:aarWrapper:generateReleaseResources
:aarWrapper:packageReleaseResources
:aarWrapper:processReleaseManifest
:aarWrapper:generateReleaseBuildConfig
:aarWrapper:processReleaseResources
:aarWrapper:generateReleaseSources
:aarWrapper:incrementalReleaseJavaCompilationSafeguard
:aarWrapper:javaPreCompileRelease
:aarWrapper:compileReleaseJavaWithJavac
:aarWrapper:processReleaseJavaRes UP-TO-DATE
:aarWrapper:transformResourcesWithMergeJavaResForRelease
:aarWrapper:transformClassesAndResourcesWithSyncLibJarsForRelease
:aarWrapper:mergeReleaseJniLibFolders
:aarWrapper:transformNativeLibsWithMergeJniLibsForRelease
:aarWrapper:transformNativeLibsWithStripDebugSymbolForRelease
:aarWrapper:transformNativeLibsWithSyncJniLibsForRelease
:aarWrapper:bundleRelease
:aarWrapper:compileReleaseSources
:aarWrapper:assembleRelease
:aarWrapper:assemble
:aarWrapper:lint FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':aarWrapper:lint'.
> com.android.tools.lint.detector.api.JavaContext.getContents()Ljava/lang/String;
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
gradle файл
apply plugin: 'java'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.0'
}
}
repositories {
jcenter()
}
allprojects {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
dependencies {
compile 'com.android.tools.lint:lint:24.3.1'
compile 'com.android.tools.lint:lint-api:24.3.1'
compile 'com.android.tools.lint:lint-checks:24.3.1'
testCompile 'junit:junit:4.11'
testCompile 'org.assertj:assertj-core:3.0.0'
testCompile 'org.mockito:mockito-core:1.9.5'
testCompile 'com.android.tools.lint:lint:24.3.1'
testCompile 'com.android.tools.lint:lint-tests:24.3.1'
testCompile 'com.android.tools:testutils:24.3.1'
}
jar {
baseName 'com.bignerdranch.linette'
version '1.0'
manifest {
attributes 'Manifest-Version': 1.0
attributes('Lint-Registry': 'com.bignerdranch.linette.registry.CustomIssueRegistry')
}
}
sourceSets {
main {
java {
srcDirs = ["lint/src/main/java"]
}
}
test {
java {
srcDirs = ["lint/src/test/java"]
}
}
}
configurations {
lintChecks
}
dependencies {
lintChecks files(jar)
}
defaultTasks 'assemble'
task install(type: Copy) {
from configurations.lintChecks
into System.getProperty('user.home') + '/.android/lint/'
}
aarWrapper gradle
apply plugin: 'com.android.library'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.0'
}
}
android {
compileSdkVersion 25
buildToolsVersion '25.0.2'
defaultConfig {
minSdkVersion 19
targetSdkVersion 25
versionCode 1
versionName '1.0'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
project.afterEvaluate {
def compileLint = project.tasks.getByPath(':aarWrapper:compileLint')
compileLint.dependsOn parent.tasks.getByName("jar")
compileLint << {
copy {
from '../build/libs'
into 'build/intermediates/lint'
}
}
}
Ответы
Ответ 1
Если ваша деактивация мгновенного запуска не работает, добавьте его в свой файл build.gradle
.
android {
lintOptions {
// if true, stop the gradle build if errors are found
abortOnError false
}
}
Затем очистите проект и запустите его.
если abortOnError false
не решит вашу проблему, вы можете попробовать следующее
lintOptions {
checkReleaseBuilds false
}
Надеюсь, что это решит вашу проблему.
Ссылка ресурса:
Ответ 2
Daniel Passos дал решение здесь в этот учебник
Игнорирование Erros
Lint является частью процесса сборки Gradle, по умолчанию, если он не завершится, ваша сборка остановится, и вы получите сообщение вроде этого:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:lint'.
> Lint found errors in the project; aborting build.
В 99% случаев люди начнут игнорировать линт вместо исправления проблем, добавив это в build.gradle
app
lintOptions {
abortOnError false
}
Но ИМХО его неправильно. Если линт говорит, у вас есть проблема, лучше всего это исправить. Lint - это инструмент, который улучшит ваше приложение и UX.
Игнорирование конкретных эрос
Иногда вам действительно нужно игнорировать некоторые ошибки lint. Например, когда вы используете webView.getSettings().setJavaScriptEnabled(true);
в своем WebView
В этом случае вы должны отключить только определенные идентификаторы вместо отключения всего lint.
lintOptions {
disable 'SetJavaScriptEnabled'
}
Вы также можете игнорировать его непосредственно в своем коде:
@SuppressLint "SetJavaScriptEnabled")
Или в вашем XML
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="SomeLintIssueIdHere" >
Если вы предпочитаете, вы можете переместить все свои правила проблем из файла lint.xml
в корневой каталог вашего проекта.
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<issue id="SetJavaScriptEnabled" severity="ignore" />
</lint>
Ответ 3
Я тестировал один и тот же код и сталкивался с тем же вопросом.
Для com.android.tools.lint
доступны новые версии. Попробуйте 25.2.0 или выше, и вы заметите, что код примера TodoDetector использует устаревшие методы.
В принципе, вам нужно сделать свой класс Detector.JavaPsiScanner
вместо Detector.JavaScanner
.
http://static.javadoc.io/com.android.tools.lint/lint-api/25.3.0/com/android/tools/lint/detector/api/Detector.JavaPsiScanner.html
Ответ 4
У меня была такая же ошибка при переходе на Android Gradle плагин 2.3.0 com.android.tools.build:gradle:2.3.0
. Проблема в моем случае заключалась в том, что плагин android-apt, который я использовал, устарел: Android Gradle плагин 2.3.0 имеет обработку аннотаций из коробки и, похоже, блокирует андроид-apt.
Прочитайте руководство по миграции и перенесите раздел "apt" зависимостей Gradle build script и "apt", а затем удалите плагин android-apt:
https://bitbucket.org/hvisser/android-apt/wiki/Migration
UPD: Проблема осталась после исправления выше. Я просмотрел ошибку stacktrace в журнале событий и выяснил, что исключение происходит в одной из моих пользовательских проверок lint (io.vokal.lint:todo:1.0.3
). Удаление его из ~/.android/lint
решило проблему.
Ответ 5
Я столкнулся с той же проблемой. Заглядывая в context.getContents()
:
return mDriver.getClient().readFile(file);
Итак, я попытался сделать это вручную следующим образом: context.getDriver().getClient().readFile(context.file)
, который выдает одно и то же сообщение об ошибке.
Мое обходное решение теперь, вместо использования context.getContents()
, я просто использую context.file
и читаю его без драйвера. Я не уверен, что это хороший способ, но для меня это работает.
Итак, здесь рабочий код:
static void someMethod(com.android.tools.lint.detector.api.Context context){
readFile(context.file)
...
}
static String readFile(File file) {
String path = file.getAbsolutePath();
Charset encoding = Charset.defaultCharset();
try {
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
} catch (IOException e){
return "";
}
}