如何从命令行使用 OkHttp 运行 Kotlin 代码?

问题描述 投票:0回答:1

我尝试从命令行在 macOS 13 上运行 Kotlin 代码,首先我安装了它

brew install kotlin

然后我创建了一个目录并下载了一些看起来相关的jar文件的最新版本:

mkdir -p /tmp/kotlin 
cd /tmp/kotlin 
curl https://repo1.maven.org/maven2/com/squareup/okhttp3/okhttp/4.11.0/okhttp-4.11.0.jar > okhttp-4.11.0.jar 
curl https://repo1.maven.org/maven2/com/squareup/okio/okio/3.3.0/okio-3.3.0.jar > okio-3.3.0.jar 
curl https://repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.8.21/kotlin-stdlib-1.8.21.jar > kotlin-stdlib-1.8.21.jar

(ChatGPT 也告诉我安装 kotlin-stdlib,我不确定这是否有意义...)

然后我创建了一个名为 OkHttpExample.kt 的示例文件,其中包含以下内容:

import java.io.IOException;
import okhttp3.OkHttpClient
import okhttp3.Request

fun main() {
    val client = OkHttpClient()

    val request = Request.Builder()
        .url("https://example.com")
        .build()

    client.newCall(request).execute().use { response ->
        if (!response.isSuccessful) throw IOException("Unexpected code $response")

        println(response.body!!.string())
    }
}

并尝试编译和运行它

kotlinc -classpath okhttp-4.11.0.jar:kotlin-stdlib-1.8.21.jar:okio-3.3.0.jar OkHttpExample.kt -include-runtime -d OkHttpExample.jar
java -classpath okhttp-4.11.0.jar:kotlin-stdlib-1.8.21.jar:okio-3.3.0.jar:OkHttpExample.jar OkHttpExampleKt

但是

java
命令失败并出现此错误:

Exception in thread "main" java.lang.NoClassDefFoundError: okio/Buffer
    at okhttp3.ResponseBody$Companion.create(ResponseBody.kt:248)
    at okhttp3.ResponseBody$Companion.create$default(ResponseBody.kt:247)
    at okhttp3.internal.Util.<clinit>(Util.kt:65)
    at okhttp3.OkHttpClient.<clinit>(OkHttpClient.kt:1073)
    at OkHttpExampleKt.main(OkHttpExample.kt:6)
    at OkHttpExampleKt.main(OkHttpExample.kt)
Caused by: java.lang.ClassNotFoundException: okio.Buffer
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 6 more
kotlin okhttp
1个回答
0
投票

解决您的具体问题

NoClassDefFoundError: okio/Buffer
表示某些代码尝试使用
okio.Buffer
类,但该类不在您放在类路径中的任何 jar 中。

这可能是因为您只是手动挑选了一些要下载的 jar,而您错过了传递依赖项。例如,您可能缺少

okio-jvm
依赖项,它是
okio
本身的依赖项。

一个解决方案是自己找到所有传递依赖项(例如通过查看 Maven Central 中的

.pom
文件)并手动下载越来越多的 jar,但这不是很实用。

推荐的替代品

相反,我在这里强烈建议 2 个选项:

  1. 创建一个“标准”Kotlin 项目并使用像 Gradle 这样的构建工具来管理依赖项和编译。它需要一些设置,但大多数人会更熟悉,您可以轻松地在网上找到示例。

  2. 如果你只是玩玩,你可以尝试使用 Kotlin Scripting

    .main.kts
    方法,这可能会简化你的工作流程,尽管这对大多数人来说并不常见。

我将在这里详细说明选项 2,因为很难找到有关它的信息,而且对于像这样的玩具项目来说更简单。

您可以使用以

.main.kts
结尾的单个 Kotlin 文件,例如
script.main.kts
,并将您的代码直接放在那里,甚至没有
main()
函数。不要手动下载 jar,而是使用文件顶部的
@file:DependsOn
添加依赖项,并使用依赖项的 maven 坐标(您不需要放置传递依赖项,只需放置您想要直接使用的依赖项):

script.main.kts
(扩展很重要!)

@file:DependsOn("com.squareup.okhttp3:okhttp:4.11.0")

import java.io.IOException
import okhttp3.OkHttpClient
import okhttp3.Request

val client = OkHttpClient()
val request = Request.Builder().url("https://example.com").build()
client.newCall(request).execute().use { response ->
    if (!response.isSuccessful) throw IOException("Unexpected code $response")

    println(response.body!!.string())
}

然后你可以用一个简单的命令编译并运行它:

kotlin script.main.kts

这里有一个更“官方”的关于

main.kts
用法的例子: https://github.com/Kotlin/kotlin-script-examples/blob/master/jvm/main-kts/MainKts.md

© www.soinside.com 2019 - 2024. All rights reserved.