请问 kotlin 如何读取 jar 包内的文本文件呢?

2020-07-05 15:15:33 +08:00
 heavyrainn

想用 kotlin 写一个程序,用 idea 建了个 gradle 工程。需要读取的文本文件放在了 src/main/resources 文件夹中,文件名 readit.txt 。然后用以下程序读,代码如下:

fun main() {
    println(getResourceAsText("readit.txt"))
}

fun getResourceAsText(path: String): String {
    return object {}::class.java.getResourceAsStream(path).bufferedReader().readText()
}

使用 idea 直接调用,可用。然后 gradle build 打包成可执行 jar 包,gradle.build 配置文件如下:

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.3.72'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

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

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

jar {
    manifest {
        attributes 'Main-Class': 'MainKt'
    }
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}

打完 jar 包后,发现 readit.txt 变成在 jar 内根目录下,然后执行程序报错如下:

Exception in thread "main" java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
        at MainKt.getResourceAsText(main.kt)
        at MainKt.main(main.kt:2)
        at MainKt.main(main.kt)
Caused by: java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
        ... 3 more

请大家指点,为啥会这样😿感谢大家

2237 次点击
所在节点    程序员
7 条回复
cppgohan
2020-07-05 15:54:25 +08:00
"kotlin.jvm.internal.Intrinsics" 这个类找不到? kotlin 的 runtime 没有打包? 或者是 classpath 设置的不对?
SoloCompany
2020-07-05 16:45:22 +08:00
为什么要构造一个多余的匿名类
napsterwu
2020-07-05 17:39:59 +08:00
jar 包需要 getResourceAsStream
napsterwu
2020-07-05 17:40:36 +08:00
看错了 无视我吧
heavyrainn
2020-07-05 19:46:49 +08:00
@SoloCompany 在 stackoverflow 直接抓来的 fun…
sorra
2020-07-05 20:07:43 +08:00
依赖项没有打进 jar ?用 Gradle shadowJar plugin 试试
heavyrainn
2020-07-06 10:41:07 +08:00
发现了原因,把 configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }改成 configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }就好了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/687306

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX