Is there any sort of tool or plugin to go from a `...
# multiplatform
h
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 ☝️
j
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)
👍 1
Copy code
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
🤔 1
e
Copy code
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
🤔 1
h
@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?
j
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
👍 1
h
@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
j
the @ephemient config is for adding support to java files inside jvm target no?
h
@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
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
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