将Kotlin文件编译为Dex会生成ClassNotFoundException(kotlin.jvm.internal.Intrinsics)

时间:2019-08-29 21:56:35

标签: android kotlin dalvik

我正在尝试创建一个命令行脚本以在我的Android设备上运行。我正在遵循此answer来用Dalvik VM运行编译的kotlin文件,但是在adb shell上运行dalvikvm -cp TestKt.zip时却遇到了以下错误:

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,因此我不确定这是否是正确的方法。 / p>

我应该如何解决该错误?

2 个答案:

答案 0 :(得分:0)

我设法将Kotlin源文件编译成可接受的Dex文件。 JesusFreke的提示确实有用,并且是问题的根源。

默认情况下,kotlin编译器已经生成了针对JRE6的Java字节码,这是Dalvik需要运行的,因此只需将Kotlin运行时包含在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用于删除Java 8功能。由于kotlin编译器默认情况下以JRE6为目标,因此无需进行重复调试。

一些对我有帮助的链接

答案 1 :(得分:0)

从输出文件夹中删除调试Apk文件解决了它 在此路径中app / build / outputs / apk / debug / myapp.apk