编译 Kotlin 文件到 Dex 产生 ClassNotFoundException (kotlin.jvm.internal.Intrinsics)
Compiling Kotlin file to Dex generates ClassNotFoundException (kotlin.jvm.internal.Intrinsics)
我正在尝试在我的 Android 设备上为 运行 创建一个命令行脚本。我正在使用 Dalvik VM 跟踪这个 answer 到 运行 编译的 kotlin 文件,但是当我在 adb 运行 dalvikvm -cp TestKt.zip
上 shell:
Exception in thread "main" java.lang.NoClassDefFoundError: Failed resolution of: Lkotlin/jvm/internal/Intrinsics;
at TestKt.main(Unknown Source:2)
Caused by: java.lang.ClassNotFoundException: Didn't find class
"kotlin.jvm.internal.Intrinsics" on path: DexPathList[[zip file "TestKt.zip"],
nativeLibraryDirectories=[/system/lib64, /system/vendor/lib64,
/system/lib64, /system/vendor/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
... 1 more
这是我要编译的简单文件 (Test.kt):
package edu.ufrn.lapps
fun main(args: Array<String>) {
println(args.size);
}
我写了一个 Makefile 来编译它(主要是因为这只是一个测试,但如果我需要依赖项,我可能会转向 Gradle):
NAME := TestKt
OUTPUT := TestKt
PKG := edu/ufrn/lapps
KFLAGS := -include-runtime
D8C := $(HOME)/Android/Sdk/build-tools/29.0.1/d8
D8FLAGS := --no-desugaring
dex:
kotlinc src/$(PKG)/Test.kt
$(D8C) $(D8FLAGS) $(PKG)/$(OUTPUT).class
zip: dex
zip $(OUTPUT).zip classes.dex
jvm:
kotlinc $(SRC)/Test.kt $(KFLAGS) -d $(OUTPUT).jar
.PHONY: clean
clean:
-rm -r META-INF/
-rm $(OUTPUT).jar $(OUTPUT).zip
我正在尝试按照 AOSP cmds 来制作我的 CLI 脚本,但我之前从未将 Java 字节码编译到 Dex,所以我不确定这是否正确方法。
我应该如何解决这个错误?
我设法将 Kotlin 源文件编译成可接受的 Dex 文件。 JesusFreke 的提示确实有帮助,并且是问题的根源。
默认情况下,kotlin 编译器已经生成了针对 JRE6 的 Java 字节码,这是 Dalvik 所需要的 运行,因此只需将 kotlin 运行time 包含在其中即可Dex 文件。
这是我所做的:
$ kotlinc src/edu/ufrn/lapps/Test.kt -include-runtime -d TestKt.jar
$ ~/sdk-patk/build-tools/29.0.1/d8 TestKt.jar --no-desugaring
$ zip TestKt.zip classes.dex
$ adb push TestKt.zip /sdcard/
$ adb shell
$ [on adb shell]: dalvikvm -cp /sdcard/TestKt.zip edu.ufrn.lapps.TestKt
根据d8 compiler文档,--no-desugaring
用于删除Java8个特征。由于 kotlin 编译器默认以 JRE6 为目标,因此不需要脱糖。
一些对我有帮助的链接:
从输出文件夹中删除 Debug Apk 文件解决了这个问题
在这个路径 app/build/outputs/apk/debug/myapp.apk
我正在尝试在我的 Android 设备上为 运行 创建一个命令行脚本。我正在使用 Dalvik VM 跟踪这个 answer 到 运行 编译的 kotlin 文件,但是当我在 adb 运行 dalvikvm -cp TestKt.zip
上 shell:
Exception in thread "main" java.lang.NoClassDefFoundError: Failed resolution of: Lkotlin/jvm/internal/Intrinsics;
at TestKt.main(Unknown Source:2)
Caused by: java.lang.ClassNotFoundException: Didn't find class
"kotlin.jvm.internal.Intrinsics" on path: DexPathList[[zip file "TestKt.zip"],
nativeLibraryDirectories=[/system/lib64, /system/vendor/lib64,
/system/lib64, /system/vendor/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
... 1 more
这是我要编译的简单文件 (Test.kt):
package edu.ufrn.lapps
fun main(args: Array<String>) {
println(args.size);
}
我写了一个 Makefile 来编译它(主要是因为这只是一个测试,但如果我需要依赖项,我可能会转向 Gradle):
NAME := TestKt
OUTPUT := TestKt
PKG := edu/ufrn/lapps
KFLAGS := -include-runtime
D8C := $(HOME)/Android/Sdk/build-tools/29.0.1/d8
D8FLAGS := --no-desugaring
dex:
kotlinc src/$(PKG)/Test.kt
$(D8C) $(D8FLAGS) $(PKG)/$(OUTPUT).class
zip: dex
zip $(OUTPUT).zip classes.dex
jvm:
kotlinc $(SRC)/Test.kt $(KFLAGS) -d $(OUTPUT).jar
.PHONY: clean
clean:
-rm -r META-INF/
-rm $(OUTPUT).jar $(OUTPUT).zip
我正在尝试按照 AOSP cmds 来制作我的 CLI 脚本,但我之前从未将 Java 字节码编译到 Dex,所以我不确定这是否正确方法。
我应该如何解决这个错误?
我设法将 Kotlin 源文件编译成可接受的 Dex 文件。 JesusFreke 的提示确实有帮助,并且是问题的根源。
默认情况下,kotlin 编译器已经生成了针对 JRE6 的 Java 字节码,这是 Dalvik 所需要的 运行,因此只需将 kotlin 运行time 包含在其中即可Dex 文件。
这是我所做的:
$ kotlinc src/edu/ufrn/lapps/Test.kt -include-runtime -d TestKt.jar
$ ~/sdk-patk/build-tools/29.0.1/d8 TestKt.jar --no-desugaring
$ zip TestKt.zip classes.dex
$ adb push TestKt.zip /sdcard/
$ adb shell
$ [on adb shell]: dalvikvm -cp /sdcard/TestKt.zip edu.ufrn.lapps.TestKt
根据d8 compiler文档,--no-desugaring
用于删除Java8个特征。由于 kotlin 编译器默认以 JRE6 为目标,因此不需要脱糖。
一些对我有帮助的链接:
从输出文件夹中删除 Debug Apk 文件解决了这个问题 在这个路径 app/build/outputs/apk/debug/myapp.apk