h

    handstandsam

    5 months ago
    Is there any sort of tool or plugin to go from a
    java-library
    to a
    kotlin("multiplatform")
    project configuration? I'm looking to slowly introduce Kotlin Multiplatform on a few modules that currently only target the JVM. I'd like a way to swap between the two so there is less hesitation from other developers to give it a try. Basically it would make the KMP module "backwards compatible" to just a java-library, and completely avoid any references to multiplatform plugins when it was switched off. Goals: • Just change "myplugin.jvm.lib" to "myplugin.kmp.lib". • This would take all
    dependencies
    from the java-library and make them dependencies on
    commonMain
    . • It would be nice to just change one line and see if it compiles to Kotlin Multiplatform as
    commonMain
    . I've given this a try, but when trying to map dependencies I get:
    Unresolved reference: implementation
    because it should be a
    commonMain
    dependency instead. I've thought about two ways of approaching this: • See if I can just iterate through declared dependencies, move them to commonMain, and remove them from the default dependencies block. • Create a custom "commonDependencies {}" extension that can then map to either. I'm looking at how I can do this, but wanted to see if any tools or processes currently exist to make a one-line backwards compatible (java-library instead of kotlin("multiplatform")) module?
    Additionally I've added
    src/main/java
    and
    src/main/kotlin
    to
    commonMain
    so that this could work.
    This is the
    java-library
    right now that has the issue saying
    Unresolved reference: implementation
    if I replace
    kotlin("jvm")
    with
    kotlin("multiplatform")
    and add the other config in the screenshot above
    Javier

    Javier

    5 months ago
    you can set your dependencies in that way or in the original dependencies block but instead of using implementation, using commonMainImplentation (or whatever you need, commonTestImplementation, commonMainApi and so on)
    plugins {
        kotlin("multiplatform")
    }
    
    kotlin {
       jvm()
    }
    
    // same as below
    kotlin {
        sourceSets {
            commonMain {
                dependencies {
                    implementation(...)
                }
            }
        }
    }
    
    // same as above
    dependencies {
        commonMainImplementation(...)
    }
    you can create a kotlin script which just copy all dependencies into a dummy autogenerated kmp project in
    commonMain
    , if it works, it is probably that your project can be moved to kmp easily (except some JVM APIs like java File which can be accessed via stdlib, but you can move all code into commonMain, so you can check that problem too
    e

    ephemient

    5 months ago
    kotlin {
        targets {
            jvm {
                withJava()
    I haven't tried but does this help? it should apply the standard Java plugin which does act on the top-level dependencies clock
    h

    handstandsam

    5 months ago
    @Javier Interesting, so just generate a separate KMP config based on the original? I understand the Java API incompatibilities, but am hoping this can surface what those are and people can move away from them. If it generates, how would it be backwards compatible in 1 line without overwriting the original build Gradle config?
    Javier

    Javier

    5 months ago
    it wouldn't be one line, there are multiple things that are not compatible that have to be moved to different places. Maybe you can create a convention plugin plus your own dsl which is identical to the java one but IMO that can be confusing when someone check it. But this solution would be one line
    For example for dependencies, you can create a implementation function which internally is calling commonMainImplementation
    but I would avoid it tbh
    h

    handstandsam

    5 months ago
    @ephemient that might work... Sound like you are saying to be more specific about config so that it applies specifically to JVM. That way when you switch, it doesn't have the issue knowing what top level "dependencies" are. That you should be good, and if you want to compile to another target, you would programmatically copy to commonMain
    @Javier good call outs. I think for long term it would be a weird thing to maintain. I'm just looking for a single line way to see if a module is Multi-platform compatible for now to toggle back and forth, and once trust is gained in KMP, can be default
    Javier

    Javier

    5 months ago
    the @ephemient config is for adding support to java files inside jvm target no?
    h

    handstandsam

    5 months ago
    @Javier @ephemient it is, but you don't have to use such explicit config typically. This might be something that would make it easier to go back and forth.
    e

    ephemient

    5 months ago
    as long as your first step is migrating from kotlin.jvm to kotlin.multiplatform with JVM target only, I think it may help
    you might need to put all your code in the jvmMain source set first, though, and migrate to commonMain after you've gotten the dependencies moved over
    h

    handstandsam

    5 months ago
    I'll give it a try now.
    Got it working with all my requirements. you typically say
    commonMain by getting
    because it exists. In the case of KMP, you just have to create the
    main
    sourceset before it is configured. So I added in a
    main by creating
    and then have
    commonMain { dependsOn(main) }
    🎉 Thanks for all the brainstorming @Javier and @ephemient!
    My project setup is pretty trivial now, but hopefully it'll expand to work in more cases. 🤞
    @Sebastian Sellmair [JB] - FYI, this is the thread about it.
    I talked with @Sebastian Sellmair [JB] earlier today and got some good pointers on this. Will build on this concept of building on top of
    commonMain
    instead of
    commonMain->main
    because that case is not supported. https://github.com/handstandsam/ShoppingApp/pull/50/files