Gradle项目:java.lang.NoClassDefFoundError:kotlin/jvm/internal/Intrinsics

Fre*_*shD 29 java exception-handling exception kotlin

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

// 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 ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

所以任何人都可以向我解释为什么异常不会被捕获.MyCustomKotlinException继承自Kotlins RuntimeException,它只是一个别名java.lang.RuntimeException.

// MyCustomKotlinException.kt
package foo

class MyCustomKotlinException(err: String) : RuntimeException(err)
Run Code Online (Sandbox Code Playgroud)

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

Update2:
我添加了第二个catch块,Throwable并捕获了以下Throwable.

java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
...
Caused by: java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics
Run Code Online (Sandbox Code Playgroud)

Update3:
将标题更改为更正错误并解决了将所有项目文件添加到jar中的问题(请参阅下面的答案).将Kotlin运行时库添加到gradle对我来说不起作用.

Sur*_*nav 23

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

  1. 单击Tools => kotlin =>在项目中配置kotlin

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

  3. 并选择版本

  4. 按好的

完成.


Fre*_*shD 18

将所有项目文件添加到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.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
Run Code Online (Sandbox Code Playgroud)

  • 我该如何在“build.gradle.kts”上执行此操作? (2认同)

Syl*_*are 11

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

gradle 文档中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) }
    })
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,当我遇到【是重复但没有设置重复处理策略】的异常时,我添加了【duplicatesStrategy = DuplicatesStrategy.EXCLUDE】就可以了 (2认同)

Pel*_*cho 6

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

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

  • 我尝试将运行时库添加到我的 `build.gradle` (`compile "org.jetbrains.kotlin:kotlin-runtime:$kotlin_version"`),但对我不起作用。 (2认同)

Sim*_*n O 6

感谢您的评论。确实compile已弃用。然而,接受的答案不适用于implementation. 所以我查找了java库插件配置implementation依赖于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) } }
}
Run Code Online (Sandbox Code Playgroud)

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.50"
    //...
}
Run Code Online (Sandbox Code Playgroud)

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

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