我刚刚开始使用 Kotlin,在理解 JAR 文件的工作原理时遇到一些问题。我有两个文件:
你好.kt
class HelloWorld {
public fun speak() {
println("hello world")
}
}
主.kt
fun main() {
val hello = HelloWorld()
hello.speak()
}
我的项目结构是:
root
|-hello.kt
|-main.kt
我的目的是构建 Kotlin 应用程序,将其类传播到不同的 JAR 文件中。 我用过
kotlinc hello.kt -d hello.jar
kotlinc main.kt -cp hello.jar -include-runtime -d main.jar
构建 JAR 文件。这两个命令执行没有任何错误。我无法理解如何执行该应用程序。
到目前为止我已经尝试过了
java -cp hello.jar -jar main.jar
运行应用程序,但出现此错误:
Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld
at MainKt.main(main.kt:2)
at MainKt.main(main.kt)
Caused by: java.lang.ClassNotFoundException: HelloWorld
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:526)
... 2 more
我也尝试遵循这个问题的答案,它显示了相同的问题,但正在运行
java -cp main.jar:hello.jar MainKt
给我以下错误
Error: Could not find or load main class MainKt
Caused by: java.lang.ClassNotFoundException: MainKt
我对 Kotlin 和 JVM 不太熟悉,但我找不到解决方案。
首先,您通常会使用 Gradle 等构建工具来为您进行编译和打包。然而,出于学习的目的,了解事物在幕后如何组合在一起总是很好的。
就您而言,您正在正确编译内容。但是,如何使用 java
命令
运行应用程序存在问题。首先,您不能混合
-cp
和 -jar
,根据 文档:
使用-jar时,指定的JAR文件是所有用户类的源,其他类路径设置将被忽略。如果您使用 JAR 文件,请参阅 jar。
简而言之,您必须选择使用
-jar
与包含所有类路径信息的可执行 jar 文件,或使用 -cp
与您需要的所有 jar + 主类名称。
由于您没有摆弄 jar 清单,因此您没有创建可执行 jar,因此您应该坚持使用
-cp
选项。您需要提供 -cp
选项中所需的所有 jar(在 linux 或 mac 上用 :
分隔,在 Windows 上用 ;
分隔),并在命令末尾提供主类名称:
java -cp "hello.jar;main.jar" MainKt
主类
MainKt
的名称源自包含 main()
函数的文件名称,如 Kotlin 文档中所定义(尽管很巧妙)。