Java 使用Gradle从Kotlin链接到JVM asm定义的类

Java 使用Gradle从Kotlin链接到JVM asm定义的类,java,gradle,android-gradle-plugin,kotlin,jasmin,Java,Gradle,Android Gradle Plugin,Kotlin,Jasmin,我对Android应用程序进行了以下设置: ├── build.gradle └── src └── main ├── AndroidManifest.xml ├── asm │   └── SomeJVMClass.j ├── kotlin │   └── activity.kt └── res └── values └── strin

我对Android应用程序进行了以下设置:

├── build.gradle
└── src
    └── main
        ├── AndroidManifest.xml
        ├── asm
        │   └── SomeJVMClass.j
        ├── kotlin
        │   └── activity.kt
        └── res
            └── values
                └── strings.xml
src/main/asm/SomeJVMClass.j
中的源文件是格式化JVM程序集(它几乎与Jasmin相同)。我想使用它从我的主要Kotlin源代码
activity.kt中定义的类

在我尝试用Gradle实现自动化之前,仅仅将文件手动组装到
build
中是没有帮助的。以下是我尝试过的:

  • 执行
    gradlebuild
    以获取骨架
    build
    目录(这当然会失败,因为Kotlin编译器没有找到
    SomeJVMClass
  • 我手动运行Krakatau,将其类文件放入
    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
    
  • 重新运行
    grade build
    ,希望Kotlin现在能找到
    .class
    文件;但没有任何改善:

  • 显然,第一个问题是,我应该将生成的
    .class
    文件放在哪里,以便Kotlin编译器可以找到它们。接下来的第二个问题是,如何实现自动化,以便在运行Kotlin编译器之前,单个
    gradle build
    命令将首先运行Krakatau汇编程序

    以下是我的源文件供参考:

    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())
      }
    }
    

    编辑:结果证明这种方法不适用于android gradle

    这与gradle比Kotlin更相关,您可以告诉gradle在编译过程中包括
    .class
    文件,方法是将语句
    compile files(“build/mediates/classes/debug”)
    添加到依赖项中


    这将把.class文件放在Kotlin应该能够找到它们的类路径上。

    听起来很有希望,但是我发现
    只支持Jar类型的本地依赖项。无法处理:build/intermediates/classes/debug
    from
    :prepareDebugDependencies
    此外,如果我将
    SomeJVMClass.class
    文件放入
    .jar
    并使用
    编译文件(“build/intermediates/classes/debug/asm.jar”)
    ,稍后在
    :transformClassesWithDexForDebug
    中失败,未捕获的翻译错误:java.lang.IllegalArgumentException:已添加:Lcom/example/JVMServer/SomeJVMClass
    @Cactus将其作为.jar文件放入构建目录可能会触发自动包含,尝试删除编译行,但保留。jar@Cactus有关子项目和自定义任务,请参阅。@Cactus此文档实际上可能会解决您的问题:
    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())
      }
    }