我有一个使用 Kotlin 的多模块化 Gradle 项目。 其中一个模块具有主要方法和对其他模块的依赖性。我需要从这个模块创建一个可执行的 jar。所以我试图通过创建这样的 Jar 任务来做到这一点
jar {
manifest {
attributes(
'Main-Class': 'my_package.RunnerKt'
)
}
from {
configurations.compileClasspath.filter{ it.exists() }.collect { it.isDirectory() ? it : zipTree(it) }
}
}
我也尝试了 Shadow Gradle Plugin .
在这两种情况下,fat jar 都是按预期创建的,它似乎包含我所有的类和依赖项。但是,当我使用 java -jar
运行 jar 时,出现以下错误:
java.lang.NoClassDefFoundError: Could not initialize class my_kotlin_object_class
其中 my_kotlin_object_class
只是一个带有一些变量的 kotlin object
。
在堆栈跟踪中没有其他可能导致此异常的异常,因此看起来它只是此类本身有问题。当我查看 jar 时,我可以在那里看到这个文件。
我不明白这是 kotlin 对象本身和可执行 jar 的问题,还是我做错了什么?
最佳答案
其实这背后还有一个异常(exception)!
奇怪的是,只要发生异常的类是 Kotlin Object
,我就无法在堆栈跟踪中看到真正的异常(我不知道为什么)。
当我将 object
更改为 class
后,我就看到了错误的真正原因。我修复了它,将其改回 object
并且一切都按预期工作。
所以问题本身是我的代码特有的,但也有人可能会从中受益。
实际上在那个对象中我正在读取一些配置文件 val url = ClassLoader.getSystemClassLoader().getResource("path_to_file")
这些文件位于我模块的 resources\configs
目录中。将它们打包到 fat jar 后,它们位于 configs 文件夹内的 jar 的根目录中。
path_to_file 是以 ./
开头的相对路径,例如./configs/my_config.json
当我在 IntelliJ 中运行项目时它工作正常,但在 fat jar 中它无法加载文件。
令我非常惊讶的是,解决方案只是从路径中删除 ./
前缀,只留下 configs/my_config.json
。一切都按预期进行。
关于java.lang.NoClassDefFoundError : Could not initialize class - Kotlin Object 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63487681/