V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
heavyrainn
V2EX  ›  程序员

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

  •  
  •   heavyrainn · 2020-07-05 15:15:33 +08:00 · 1737 次点击
    这是一个创建于 515 天前的主题,其中的信息可能已经有所发展或是发生改变。

    想用 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
    

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

    7 条回复    2020-07-06 10:41:07 +08:00
    cppgohan
        1
    cppgohan  
       2020-07-05 15:54:25 +08:00   ❤️ 1
    "kotlin.jvm.internal.Intrinsics" 这个类找不到? kotlin 的 runtime 没有打包? 或者是 classpath 设置的不对?
    SoloCompany
        2
    SoloCompany  
       2020-07-05 16:45:22 +08:00
    为什么要构造一个多余的匿名类
    napsterwu
        3
    napsterwu  
       2020-07-05 17:39:59 +08:00
    jar 包需要 getResourceAsStream
    napsterwu
        4
    napsterwu  
       2020-07-05 17:40:36 +08:00
    看错了 无视我吧
    heavyrainn
        5
    heavyrainn  
    OP
       2020-07-05 19:46:49 +08:00
    @SoloCompany 在 stackoverflow 直接抓来的 fun…
    sorra
        6
    sorra  
       2020-07-05 20:07:43 +08:00
    依赖项没有打进 jar ?用 Gradle shadowJar plugin 试试
    heavyrainn
        7
    heavyrainn  
    OP
       2020-07-06 10:41:07 +08:00
    发现了原因,把 configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }改成 configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }就好了
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2876 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 11:02 · PVG 19:02 · LAX 03:02 · JFK 06:02
    ♥ Do have faith in what you're doing.