Linking to JVM asm-defined classes from Kotlin using Gradle

Viewed 577

I have the following setup for an Android app:

├── build.gradle
└── src
    └── main
        ├── AndroidManifest.xml
        ├── asm
        │   └── SomeJVMClass.j
        ├── kotlin
        │   └── activity.kt
        └── res
            └── values
                └── strings.xml

The source file in src/main/asm/SomeJVMClass.j is Krakatau format JVM assembly (it's almost the same as Jasmin). I would like to use the class it defines from my main Kotlin source activity.kt.

Before I even get to trying to automate this with Gradle, just assembling the file manually into build doesn't help. Here's what I tried:

  1. Do a gradle build to get the skeleton build directory (this of course fails with the Kotlin compiler not finding SomeJVMClass)
  2. I run Krakatau manually to put its class files in build/intermediates/classes/{debug,release}:

    $ for flavor in debug release; do ~/prog/jvm/krakatau/assemble.py -out build/intermediates/classes/$flavor -r src/main/asm ;done
    
    Processing file src/main/asm/SomeJVMClass.j, 1/1 remaining
    Class written to build/intermediates/classes/debug/com/example/JVMServer/SomeJVMClass.class
    
    Processing file src/main/asm/SomeJVMClass.j, 1/1 remaining
    Class written to build/intermediates/classes/release/com/example/JVMServer/SomeJVMClass.class
    
  3. Re-run grade build with the hope that Kotlin will now find the .classfiles; but no improvement whatsoever:

:compileDebugKotlin
e: /home/cactus/prog/android/kotlin-asm/src/main/kotlin/activity.kt (3,20): 
   Unresolved reference: JVMServer
e: /home/cactus/prog/android/kotlin-asm/src/main/kotlin/activity.kt: (12,14): 
   Unresolved reference: SomeJVMClass

So the first question is, obviously, where do I put the resulting .class files so that the Kotlin compiler can find them. And the second, follow-up question, is how do I automate that so that a single gradle build command will run the Krakatau assembler first, before running the Kotlin compiler.

For reference, here are my source files:

src/main/asm/SomeJVMClass.j:

.class public com/example/JVMServer/SomeJVMClass
.super java/lang/Object

.method public static foo: ()Ljava/lang/String;
  .code stack 2 locals 0
    ldc "JVM bytecode works"
    areturn
  .end code
.end method

.end class  

src/main/kotlin/activity.kt:

package com.example.JVMClient

import com.example.JVMServer.SomeJVMClass    
import android.app.Activity
import android.os.Bundle

class MainActivity: Activity() {
  protected override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setTitle(SomeJVMClass.foo())
  }
}
1 Answers
Related