【问题标题】:Custom linting rules failing with com.android.tools.build:gradle:2.3.0自定义 linting 规则因 com.android.tools.build:gradle:2.3.0 失败
【发布时间】:2017-07-31 23:53:51
【问题描述】:

我和我的团队开发 Android 应用,并决定了所有人都应该遵循的编码准则。因此,我开始实施自定义 lint 规则,该规则可以在 here 找到,并将其添加到我们在 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 一切正常时,会检查自定义规则并构建应用程序。

我尝试在 lint 存储库中更新 gradle,但不幸的是,我在第 72 行的 TodoDetector 中遇到了完全相同的问题。在 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'
        }
    }
}

【问题讨论】:

  • 您是否尝试过重新构建项目并在禁用即时运行后运行?
  • @pRaNaY 我目前不是即时运行的忠实拥护者,并且将其停用。不幸的是,问题仍然存在。

标签: java android-studio android-gradle-plugin build.gradle lint


【解决方案1】:

我遇到了同样的问题。调查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 "";
    }
}

【讨论】:

    【解决方案2】:

    我在迁移到 Android Gradle 插件 2.3.0 com.android.tools.build:gradle:2.3.0 时遇到了同样的错误。我的问题是我使用的 android-apt 插件已被弃用:Android Gradle 插件 2.3.0 具有开箱即用的注释处理,并且似乎阻止了 android-apt。

    阅读迁移指南并迁移 gradle 构建脚本的“apt”部分和“apt”依赖项,然后删除 android-apt 插件: https://bitbucket.org/hvisser/android-apt/wiki/Migration

    UPD:在上述修复后问题仍然存在。我查看了事件日志中的错误堆栈跟踪,发现异常发生在我的一个自定义 lint 检查器 (io.vokal.lint:todo:1.0.3) 中。从~/.android/lint 中删除它解决了这个问题。

    【讨论】:

    • 您好,谢谢您的回复,我们的 gradle 脚本中没有 android-apt... 我还从 ~/.android/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

    【讨论】:

    • 感谢您的回复,我已更新为'com.android.tools.lint:lint:25.2.0' 并将Detector.JavaScanner 替换为Detector.JavaPsiScanner。不幸的是,我仍然有同样的错误信息。然而,唯一的区别是它现在引用了新方法createPsiVisitor
    【解决方案4】:

    Daniel Passos 在this tutorial 中给出了解决方案

    忽略错误

    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% 的情况下,人们会开始忽略 lint 而不是解决问题,将其添加到 build.gradle 应用程序

    lintOptions {   
        abortOnError false   
    } 
    

    但恕我直言,这是错误的。如果 lint 说明问题,那么最好的办法就是解决它。 Lint 是一种使您的应用程序和用户体验更好的工具。

    忽略特定错误

    有时您确实需要忽略一些 lint 错误。例如,当您在 WebView 中使用 webView.getSettings().setJavaScriptEnabled(true);

    在这种情况下,您应该只禁用特定的 id 而不是禁用整个 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>
    

    【讨论】:

    • 感谢您的重播,但是您的回答都没有解决我的问题。在我们的自定义 linting 项目中,将“com.android.tools.build:gradle:2.2.0”更改为“com.android.tools.build:gradle:2.3.0”后,我无法再构建测试。更改 linting 选项不是一个可行的解决方案。非常欢迎您查看找到的代码库 here
    【解决方案5】:

    如果您的即时运行停用无效,请将其添加到您的 build.gradle 文件中。

    android {
        lintOptions {
            // if true, stop the gradle build if errors are found
            abortOnError false
        }
    }
    

    然后清理您的项目并运行。

    如果abortOnError false不能解决您的问题,那么您可以尝试以下方法

    lintOptions {
        checkReleaseBuilds false
    }
    

    希望它能解决您的问题。

    资源链接:

    1. https://android.googlesource.com/platform/tools/base/+/e6a5b9c7c1bca4da402de442315b5ff1ada819c7
    2. gradle build fails on lint task

    【讨论】:

      猜你喜欢
      • 2018-12-07
      • 2019-12-12
      • 2013-10-17
      • 2019-12-23
      • 2012-10-17
      • 2019-10-05
      • 1970-01-01
      • 1970-01-01
      • 2015-06-15
      相关资源
      最近更新 更多