我尝试从命令行在 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
NoClassDefFoundError: okio/Buffer
表示某些代码尝试使用 okio.Buffer
类,但该类不在您放在类路径中的任何 jar 中。
这可能是因为您只是手动挑选了一些要下载的 jar,而您错过了传递依赖项。例如,您可能缺少
okio-jvm
依赖项,它是 okio
本身的依赖项。
一个解决方案是自己找到所有传递依赖项(例如通过查看 Maven Central 中的
.pom
文件)并手动下载越来越多的 jar,但这不是很实用。
相反,我在这里强烈建议 2 个选项:
创建一个“标准”Kotlin 项目并使用像 Gradle 这样的构建工具来管理依赖项和编译。它需要一些设置,但大多数人会更熟悉,您可以轻松地在网上找到示例。
如果你只是玩玩,你可以尝试使用 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