https://kotlinlang.org logo
#gradle
Title
y

Youssef Shoaib [MOD]

08/02/2023, 4:30 AM
I'm trying to share code between desktop and android. I've been successful in defining a custom source set that the 2 depend on, but the issue is that in the sourceset I can't access jvm apis. I tried using the
targetHierarchy
experimental API, but I can't figure out how to declare a group as jvm-only:
Copy code
targetHierarchy.custom {
    common {
      group("jvm") {
        withJvm()
        withAndroidTarget()
      }
    }
  }
in the generated
jvmMain
and
jvmTest
, I still don't have access to jvm apis
for now I think the best alternative is to move JVM common code into another JVM-only module and then import it into your Android and JVM targets
j

Jeff Lockhart

08/02/2023, 4:38 AM
You should name your group something other than
"jvm"
, as the
jvm
target itself uses this name. I have a common JVM + Android intermediate source set that I've set up in almost this exact way. I'm just calling it
group("jvmCommon")
is the only difference. I have not had an issue accessing JVM APIs. I've run into some other hurdles, but have mostly found workable resolutions for them all.
y

Youssef Shoaib [MOD]

08/02/2023, 4:38 AM
Oooof yeah it looks like quite the mess of a feature to support! My project layout is the default compose kmp one which has a common module and separate desktop and android modules, so I think in common I'll stick to only "publishing" a JVM module. The disadvantage is I won't be able to do expect/actual with differing behaviour on android vs ios
@Jeff Lockhart I would love to see some example code of that! My Jvm target is named "desktop", so I think it's not a name clash issue, but I'll try that and see if it works
j

Jeff Lockhart

08/02/2023, 4:41 AM
Interesting, if it does make a difference. I'm going to be releasing my library soon, so you'll be able to check it out then.
My full source set hierarchy and targets are:
Copy code
targetHierarchy.custom {
    common {
        group("jvmCommon") {
            withAndroidTarget()
            withJvm()
        }
        group("nativeCommon") {
            group("apple") {
                withApple()
            }
            group("native") {
                withLinux()
                withMingw()
            }
        }
    }
}

androidTarget()
jvm()
iosArm64()
iosSimulatorArm64()
iosX64()
macosX64()
macosArm64()
linuxX64()
mingwX64()
y

Youssef Shoaib [MOD]

08/02/2023, 4:51 AM
Looks like it's working now! I can access Jvm APIs, and even use context receivers! In fact, I renamed it back to "jvm" instead of "jvmCommon" and everything still works just fine! I think my IDE was just being a bit stupid.
🎉 1
j

Jeff Lockhart

08/02/2023, 5:12 AM
The main issue I've had to workaround is the fact that there's no commonization for dependency APIs, similar to what native targets do. I'm using a dependency that has separate JVM and Android artifacts, where the APIs are 99% the same. I add the platform-specific dependencies to the jvm and android targets, but to get access to the API in the shared intermediate source set, I add the JVM platform dependency to the intermediate source set as
compileOnly
. This mostly works, but I still needed a workaround to fix false positive errors in the IDE, where the JVM and Android dependency APIs clash, since the Android target ends up seeing both platform dependencies.
t

takahirom

08/08/2023, 2:35 AM
@Jeff Lockhart Thanks for your information. I have a similar problem that I see the error that IDE says Unresolved reference "java.io.File". May I ask what dependency you added for the JVM platform dependency?
j

Jeff Lockhart

08/08/2023, 3:49 AM
I didn't need to add any explicit dependency in order to access JVM platform APIs. The fact that the source set has only JVM child source sets seems to enable access to these APIs. You might try removing the "desktop" name for your
jvm
source set, as this seems to have helped resolve the issue for Youssef. He was able to change the name back after it began working.
t

takahirom

08/09/2023, 12:50 AM
Thanks. I was able to fix it by removing the .idea folder and importing the project again.
👍🏼 1
2 Views