Multiplatform and mulitple jvm targets


We have a library to be shared between jvm(server) and jvm(android). It is to move to multi-platform because services like http can vary between these platforms.

It seems ‘import java.???’ is simply not possible in common. This makes sense for many calls, as these will involve calls to the jvm platform itself. However I would have thought some calls in things like java.lang.math would simply produce inline code, but if I have it correctly, I would it seems nothing can be imported from java?

This brings to the main question, with code that is common between two platforms, is there a standard or recommended way to share code between two platforms? I was thinking of a source folder added to the source folders for both projects, but perhaps there is a better way?


Your problem is not strictly related to Kotlin, you should deal with it same as a Java problem.
You can use a multi-release JAR, as example, or deploy two versions with same interfaces.

What solution wish you take in a Java project?


Consider using the Ktor HTTP multiplatform client.


What you want is actually possible, but tricky. All the java types need to be made available through expect and “implemented” through a typealias. This can even be done in a source set that is actually shared by both android and java (I don’t know what happens if this sourceset is also the one with the expect). This shared source, while built correctly by gradle, will not be recognised by intellij as “jvm” based and will not get the standard library in its path.


May be what you want to do is something similar to this:


Could be. I think we have had the problem that adding an extra source set seems to create an extra target. Could be a result of the syntax of using Kotlin DSL in place of groovy. I will have a further look.


What you may have ran up against is the variant resolution problem. In gradle, variants are distinguished using attributes. Kotlin (multiplatform and plain) adds some attributes designating such a target. However if you have multiple variants that the kotlin attributes don’t distinguish gradle no longer knows which variant of the library to pick. The way to resolve it is to define additional attributes that distinguish.

There is however an additional complication, that is how to deal with attributes when none is specified. Attributes can add resolution rules where you can influence for example that jvm1.8 is to be preferred over jvm1.6 in such a case. The attribute resolution rules should be specified for all subprojects as well, and you have to specify the attributes on the relevant source sets. This is all done for you by the kotlin plugin, but not if you have “extended” source sets. Perhaps the easiest way to do this is with a custom “plugin”.