首页 > 解决方案 > Android 构建项目失败(原因:java.lang.ClassNotFoundException:org.antlr.v4.runtime.CharStreams)

问题描述

FAILURE:构建失败并出现异常。

执行 org.jetbrains.kotlin.gradle.internal.KaptExecution java.lang.reflect.InvocationTargetException 时发生故障(无错误消息)

引起:java.lang.ClassNotFoundException:org.antlr.v4.runtime.CharStreams ... 45 更多

Build.gradle 文件(模块):

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"

    defaultConfig {
        applicationId "org.bloodwyn.userdata"
        minSdkVersion 24
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    configurations.all() {
        resolutionStrategy.force "org.antlr:antlr4-runtime:4.5.3"
        resolutionStrategy.force "org.antlr:antlr4-tool:4.5.3"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    dataBinding {
        enabled = true
    }

    compileOptions {
        coreLibraryDesugaringEnabled = true
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_1_8.toString()
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.0.9"

    //kotlin
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

    //android
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation "androidx.recyclerview:recyclerview:1.1.0"
    // For control over item selection of both touch and mouse driven selection
    implementation "androidx.recyclerview:recyclerview-selection:1.1.0-rc01"

    //retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

    //okhttp
    implementation 'com.squareup.okhttp3:okhttp:4.7.2'
    implementation 'com.squareup.okhttp3:logging-interceptor:4.7.2'

    //rxjava
    implementation 'io.reactivex.rxjava3:rxjava:3.0.2'
    implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
    implementation "com.github.akarnokd:rxjava3-retrofit-adapter:3.0.0"

    //room
    def room_version = "2.2.5"

    implementation "androidx.room:room-runtime:$room_version"
    implementation "androidx.room:room-rxjava2:$room_version"
    kapt "androidx.room:room-compiler:$room_version"

    //tests
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.ext:truth:1.2.0'
    androidTestImplementation 'com.google.truth:truth:1.0'
    androidTestImplementation 'androidx.test:core:1.2.0'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test:rules:1.2.0'
    debugImplementation 'androidx.fragment:fragment-testing:1.2.5'

    //mock http server for tests
    testImplementation 'com.squareup.okhttp3:mockwebserver:4.6.0'

    //room test
    testImplementation "androidx.room:room-testing:$room_version"
    
}

build.gradle 项目:

buildscript {
    ext.kotlin_version = '1.3.72'
    repositories {
        google()
        jcenter()
        
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.0.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

我添加了这个:

configurations.all() {
        resolutionStrategy.force "org.antlr:antlr4-runtime:4.5.3"
        resolutionStrategy.force "org.antlr:antlr4-tool:4.5.3"
}

因为如果我没有收到“用于代码生成的 ANTLR 工具版本 4.5.3 与当前运行时版本 4.7.1 用于解析器编译的 ANTLR 运行时版本 4.5.3 与当前运行时版本 4.7.1 不匹配”异常

标签: androidandroid-studiokotlinandroid-gradle-pluginbuild.gradle

解决方案


我有一些建议可以帮助一些人使用 Android Studio 和 Gradle 自动重新生成 ANTLR4 代码以在 Android 上使用。我的项目在这里找到了我的设置的完整工作示例。

首先,回答发帖人的部分问题。和包似乎过时了org.antlr:antlr4-runtime:4.5.3org.antlr:antlr4-tool:4.5.3尽管许多较早的帖子建议使用这些依赖项。我发现以下内容将包括最新版本的 ANTLR4(查看 ANTLR4 存储库以获取更新版本):

dependencies {
    // ...
    implementation 'org.antlr:antlr4:4.9.1'
}

对于典型的 Android 应用程序,我们需要先应用以下 stock 插件:

apply plugin: 'com.android.application'

问题是这破坏了 Gradle 与 ANTLR4 插件的使用。一种解决方法是antlr4在您的 shell 路径中安装该实用程序,然后在应用程序build.gradle配置中执行以下操作:

/* NOTE: The gradle plugin with Android does not work, this is a shell command within the standard system paths. */
def generateAntlrJava(String grammarFile) {
    def scriptRunCmd = "antlr -o app/src/main/antlr-gen -package 'com.my.package.name' -Dlanguage=Java" +
            " -listener -visitor -long-messages -lib 'path/to'" +
            " -Xexact-output-dir 'path/to" + grammarFile + "'";
    def cmdResult = ['bash', '-c', scriptRunCmd].execute();
    cmdResult.waitFor();
    return cmdResult.text
}

task PreBuildGenAntlr4JavaSources {
    println 'REMOVING OLD ANTLR4 JAVA SOURCES ==> '
    file(new File('app/src/main/antlr-gen')).deleteDir()
    println 'GENERATING ANTLR4 JAVA SOURCES ==> '
    file(new File('app/src/main/antlr-gen')).mkdirs()
    generateAntlrJava("MyScriptLexer.g4")
    generateAntlrJava("MyScriptParser.g4")
    outputs.upToDateWhen { false } /* Make the task run every time (no UP-TO-DATE skippage) */
}
preBuild.dependsOn PreBuildGenAntlr4JavaSources

task cleanPreBuildGenAntlr4JavaSources {
    println 'REMOVING OLD ANTLR4 JAVA SOURCES ==> '
    file(new File('app/src/main/antlr-gen')).deleteDir()
    println 'GENERATING ANTLR4 JAVA SOURCES ==> '
    file(new File('app/src/main/antlr-gen')).mkdirs()
    generateAntlrJava("MyScriptLexer.g4")
    generateAntlrJava("MyScriptParser.g4")
}
clean.dependsOn cleanPreBuildGenAntlr4JavaSources

而已。唯一适用于我的用例的解决方案:)


推荐阅读