Пользовательские правила 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 "";
    }
}