2

I'm trying to create a command line script to run on my Android device. I'm following this answer to run the compiled kotlin file with Dalvik VM, but I'm getting the following error when I run dalvikvm -cp TestKt.zip on adb 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

This is the simple file (Test.kt) that I'm trying to compile:

package edu.ufrn.lapps

fun main(args: Array<String>) {
    println(args.size);
}

I wrote a Makefile to compile it (mainly because this is just a test, but I'll probably move to Gradle once I need dependencies):

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

I'm trying to follow the AOSP cmds to make my CLI script, but I've never compiled Java bytecode to Dex before, so I'm not sure if this is the right way to do it.

How should I go about fixing this error?

Eduardo macedo
  • 762
  • 1
  • 4
  • 16
  • 1
    I think you're on the right track, but it looks like you need to figure out how to include the kotlin framework in the dex file. I'm not familiar with exactly how that works normally, so I can't really help with specifics. – JesusFreke Aug 29 '19 at 22:49
  • Ooh, I thought the kotlin compiler did that for me. I'll look more into it. If that's the case, I think I'll have more luck using gradle to automate the build process for me. – Eduardo macedo Aug 30 '19 at 12:58

2 Answers2

2

I managed to compile the Kotlin source file into an acceptable Dex file. The tip by JesusFreke really helped and was the source of the problem.

The kotlin compiler already generates Java bytecode targeting JRE6 by default, which is what Dalvik needs to run, so it was just a matter of including the kotlin runtime into the Dex file.

Here is what I did:

$ 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

According to the d8 compiler documentation, the --no-desugaring is used to remove Java 8 features. Since the kotlin compiler targets JRE6 by default, desugaring is not needed.

Some links that helped me:

Eduardo macedo
  • 762
  • 1
  • 4
  • 16
0

Removing Debug Apk file from outputs folder solved it in this path app/build/outputs/apk/debug/myapp.apk

Islam Ahmed
  • 668
  • 9
  • 19