【问题标题】:Gradle Project: java.lang.NoClassDefFoundError: kotlin/jvm/internal/IntrinsicsGradle 项目:java.lang.NoClassDefFoundError:kotlin/jvm/internal/Intrinsics
【发布时间】:2017-05-26 08:56:54
【问题描述】:

我正在开发一个 Java 项目,在这个项目中,我第一次尝试使用 Kotlin。我开始使用 Intellij Idea 中提供的 JavaToKoltin 转换器将一些类转换为 Kotlin。除其他外,我的自定义异常现在已转换为 Kotlin。但是有了这个,异常处理就不再正确了。
如果我在 java 代码中抛出我的自定义异常之一(例如MyCustomKotlinException.kt),则不会捕获异常(参见下面的代码)。

// Example.java
package foo    

import java.util.*;
import java.lang.*;
import java.io.*;
import foo.MyCustomKotlinException;

class Example
{
    public static void main (String[] args)
    {
        try {
            // Do some stuff
            // if Error
            MyCustomKotlinException e = new MyCustomKotlinException("Error Message");
            throw e;
        } catch (MyCustomKotlinException e) {  // <-- THIS PART IS NEVER REACHED
            // Handle Exception
        } catch (Throwable e) {
            e.printStackTrace(); <-- This is catched
        } finally {
            // Finally ...
        }
    }
}

那么任何人都可以向我解释为什么异常没有被捕获。 MyCustomKotlinException 继承自 Kotlins RuntimeException,它只是 java.lang.RuntimeException 的别名。

// MyCustomKotlinException.kt
package foo

class MyCustomKotlinException(err: String) : RuntimeException(err)

更新:
我将 throw 部分分成 2 行(实例创建和 throwing),发现问题不在于 throwing。实例创建后会留下 try 块。我创建这个 Kotlin 类的实例有什么问题吗?

更新 2:
我用 Throwable 添加了第二个 catch 块,然后捕获了以下 Throwable。

java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
...
Caused by: java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics

更新3:
将标题更改为更正错误并修复了将所有项目文件添加到 jar 的问题(请参见下面的答案)。 将 Kotlin 运行时库添加到 gradle 对我不起作用。

【问题讨论】:

  • 请提供完整的minimal reproducible example,例如带有那个kotlin源代码。
  • @GhostCat 这对你来说够了吗?
  • 它需要足够多,以便人们可以重现该问题。看起来像现在。
  • @FreshD 我无法使用您提供的代码重现该问题。
  • @Christian 是的,你是对的。我刚刚尝试了这个例子,它可以工作。但是异常类看起来相同,但名称不同,并且 try catch 中的实例创建也是相同的,所以不知道为什么它只适用于示例。

标签: java exception exception-handling kotlin


【解决方案1】:

将所有项目文件添加到 jar 为我解决了这个问题。我将以下行添加到我的build.gradle

jar {
    manifest {
        attributes ...
    }
    // This line of code recursively collects and copies all of a project's files
    // and adds them to the JAR itself. One can extend this task, to skip certain
    // files or particular types at will
    from { configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
}

更新:根据下面的this 答案将configurations.compile.collect 更改为configurations.compileClasspath.collect

【讨论】:

  • 现在使用configurations.compileClasspath 代替上面提到的@simon-o 的configurations.compile
  • 能否请您一步一步告诉我您是如何生成项目的 JAR 的?我对此有很大的问题
  • 如何在build.gradle.kts 上执行此操作?
  • @mending3 如果将上述行添加到build.gradle.kts 会发生什么?
【解决方案2】:

您需要使用 kotlin 配置您的项目。 所以在 Android Studio 中:

  1. 点击工具 => kotlin => 在项目中配置 kotlin

  2. 然后在对话框中检查:所有包含 kotlin 文件的模块

  3. 并选择版本

  4. 按下确定

完成。

【讨论】:

    【解决方案3】:

    这个错误可能是由于简单的 jar 任务没有获取其所有运行时依赖项。

    来自gradle documentation,在您的build.gradle.kts 中,您可以创建“fatJar”任务或将其添加到您的 jar 任务中:

    tasks.withType<Jar> {
        // Otherwise you'll get a "No main manifest attribute" error
        manifest {
            attributes["Main-Class"] = "com.example.MainKt"
        }
    
        // To add all of the dependencies
        from(sourceSets.main.get().output)
    
        dependsOn(configurations.runtimeClasspath)
        from({
            configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) }
        })
    }
    

    【讨论】:

      【解决方案4】:

      我要说的是,您正在尝试在没有 kotlin-runtime 库的情况下运行 Kotlin 代码

      检查您使用的系统并添加必要的 jar 文件。您可以通过将项目打包到 .jar 文件并使用 runtime library 运行它来验证这是您的问题

      【讨论】:

      • 我尝试将运行时库添加到我的build.gradle (compile "org.jetbrains.kotlin:kotlin-runtime:$kotlin_version"),但对我不起作用。
      • 完美!这个对我有用。添加“kotlin-runtime-1.2.71.jar”然后重建。那个错误消失了。 Kotlin 的工作就像一个魅力!谢谢!
      • 也为我工作,虽然 kotlin-runtime 已被 kotlin-stdlib 弃用。
      【解决方案5】:

      遇到了同样的问题,在控制台中用 Ant 编译我的项目。我已经将 kotlin-stdlib.jar 加入到类路径中,问题已经消失了。

      【讨论】:

        【解决方案6】:

        感谢您的评论。事实上compile 已被弃用。但是,接受的答案不适用于implementation。所以我查了java library plugin configurationimplementation依赖于compileClasspath。

        所以我现在的解决方案是添加

        jar {
            manifest {
                attributes ...
            }
            // This line of code recursively collects and copies all of a project's files
            // and adds them to the JAR itself. One can extend this task, to skip certain
            // files or particular types at will
            from { configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
        }
        

        dependencies {
            implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.50"
            //...
        }
        

        我觉得这应该由 org.jetbrains.kotlin.jvm 插件来完成。

        在 build.gradle 文件的依赖项中使用 compile 而不是 implementation 为我解决了这个问题。

        【讨论】:

        • implementationcompile 更新。不应该用于替换
        • @Kishita 感谢您的评论。你是绝对正确的,编译不应该再使用了。我一直在寻找更好的选择并更新了我的答案。
        • 哦,顺便说一句,您不能使用configurations.implementation.collect或configurations.api.collect的原因是它们无法解决。
        【解决方案7】:

        添加以下内容为我解决了这个问题:

        dependencies {
            "kotlinCompilerClasspath"(fileTree("libs/gradle-plugins/kotlin"))
        }
        

        这里是libs/gradle-plugins/kotlin的内容:

        annotations-13.0.jar
        commons-codec-1.9.jar
        commons-logging-1.2.jar
        gradle-download-task-3.4.3.jar
        gson-2.8.5.jar
        httpclient-4.5.3.jar
        httpcore-4.4.6.jar
        kotlin-android-extensions-1.3.40.jar
        kotlin-annotation-processing-gradle-1.3.40.jar
        kotlin-build-common-1.3.40.jar
        kotlin-compiler-1.3.40.jar
        kotlin-compiler-embeddable-1.3.40.jar
        kotlin-compiler-runner-1.3.40.jar
        kotlin-daemon-client-1.3.40.jar
        kotlin-gradle-plugin-1.3.40.jar
        kotlin-gradle-plugin-api-1.3.40.jar
        kotlin-gradle-plugin-model-1.3.40.jar
        kotlin-reflect-1.3.40.jar
        kotlin-runtime-1.2.71.jar
        kotlin-script-runtime-1.3.40.jar
        kotlin-scripting-common-1.3.40.jar
        kotlin-scripting-compiler-embeddable-1.3.40.jar
        kotlin-scripting-compiler-impl-embeddable-1.3.40.ja
        kotlin-scripting-jvm-1.3.40.jar
        kotlin-stdlib-1.3.40.jar
        kotlin-stdlib-common-1.3.40.jar
        kotlin-stdlib-jdk7-1.3.40.jar
        kotlin-stdlib-jdk8-1.3.40.jar
        kotlinx-coroutines-core-1.1.1.jar
        org.jetbrains.kotlin.jvm.gradle.plugin-1.3.40.jar
        trove4j-1.0.20181211.jar
        

        完整的gradle.build.kts(离线设置):

        buildscript {
            dependencies {
                classpath(fileTree("libs/gradle-plugins/kotlin"))
            }
        }
        
        plugins {
            java
            `java-library`
        }
        
        apply(plugin = "kotlin")
        
        version = "2019.06.1"
        
        tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
            kotlinOptions.jvmTarget = "12"
        }
        
        repositories {
            flatDir {
                dirs("libs/compile")
                dirs("libs/provided")
            }
        }
        
        dependencies {
            "kotlinCompilerClasspath"(fileTree("libs/gradle-plugins/kotlin"))
            compileOnly(":javaee-api-8.0")
            api(":kotlin-stdlib-common-1.3.40")
            api(":kotlin-stdlib-1.3.40")
            api(":kotlin-stdlib-jdk7-1.3.40")
            api(":kotlin-stdlib-jdk8-1.3.40")
            api(":gson-2.8.5")
        }
        

        【讨论】:

          【解决方案8】:

          在我的例子中,settings.gradle 中的 enableFeaturePreview 在迁移到 Kotlin 1.3 时导致了这个问题。

          【讨论】:

            猜你喜欢
            • 2018-09-03
            • 1970-01-01
            • 1970-01-01
            • 2020-05-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多