Kotlin (Mobile Android/IOS) Library Imports Question


#1

I am using the project structure you get when you select the project type in the title
with the added Shared Code module as per the multiplatform Android & IOS tutorial instructions.

While I understand that the common module has to be kotlin, since it is interoperable with java should I not be able to import a set of java data model classes to use with the common.kt file in the src/commonMain/kotlin code subdirectory ?

If i add a libs subdirectory at the module root (just to test the viability of using the library) and put
my prebuilt java jar containing my data classes in there , and add it as a dependancy to the module representing the source in androidMain/kotlin/ . I can import my java classes and use them in actual.kt

if i do the exact same dependancy add to the module representing commonMain/kotlin i cannot import the java classes, the import does not see the jar at all

i see that the iml file for the SharedCode_androidMain module has an entry specifying the classes from the jar
and that the SharedCode_commonMain does not, even though i execute the exact same steps through adding dependencies i the project structure popup.

If this is not “legal” how is Idea/kotlin preventing the dependency from being valid at least for the code editing?

I was hoping to avoid having to convert all my java data classes to kotlin so that I can eventually access and use them on the individual platforms (well specifically ios as I can already use them on android).


#2

Long answer short. No you can’t use java classes in Kotlin common code.
You are right and wrong about the fact that kotlin is interoperable with java. It only is as long as you target the jvm (normal kotlin or android). If you compile to native, javascript or multiplatform common code it’s not.
The reason is pretty simple. When compiling kotlin for the jvm you can of cause use all jvm libraries. Kotlin is designed to allow this. It is however not possible to change a java library into native code or js. That is the reason why you can’t use java libraries in K/N or Kotlin JS and it’s also true for multiplatform common code.

I don’t think there is a good way around that. Luckily idea has a few features which allow you to convert java code to kotlin automatically. Not sure how well they work though as I have not used them myself.


#3

Thanks, I suspected it was not going to be that easy with the data classes.
Was a bit confused by how Idea silently prevented the imports from working, when not too familiar with Idea one is unsure if what you are trying to do is not legal or you are just doing something wrong, when the IDE does not tell you it prevented something…maybe

So having worked through some examples of conversion of my data classes I have to conclude that using Kotlin multiplatform (despite its obvious advantages with business logic reuse) is actually likely going to be the harder and more issues to overcome alternative than just rewriting all of my android code in swift (maybe not in the long, long run, but for now…).

The problem with a fairly complex set of java data classes (with various collection types, some of which hold instances of “children” classes of the same types as the parents, and various other hierarchical complexes) being translated to Kotlin is that you pretty much need to review each class line by line to see if things will still be the way they need to be after the automated conversion (as nice as that feature is). And then there is the translation to objc for the native platform, which introduces more conversions of types and I have already seen some inconsistencies and problems with the generated results, and finally how will Swift interpret the platform classes in terms of what is going on with the nested collections in that context.
I had initially found a different but related set of issues with j2objc as well.

Then on top of that there is the nightmare of the optionals and what Kotlin does to the java nullable properties, then what objc results, then again swift which handles optionals just somewhat differently than kotlin it seems

So if you knew all of that before you started with java you could probably construct things in a way that you could be reasonaby assured would translate as needed, but of course the java classes were written without that foresight, and if starting from scratch now would just write them in Kotlin instead.

Almost all the multiplatform examples are so trivial when it comes to what actual data types are being multiplatformed used, and as soon as you get into a real non-trivial situation with a legacy data model the wheels come off pretty fast, and in my case eventually overwhelming the advantages of the mechanism.


#4

Well, kotlin multiplatform is still in development and I think they focus mostly on gradle so I’m not surprised that there are still a few smaller issues.

I’m not sure about the issues you have with kotlin being translated to native. I personally don’t have much experience with multiplatform in kotlin and none with native, so yeah.
Another thing to consider is that kotlin native is still in beta so there might be a few problems. I’m sure the kotlin team would love the feedback and bug-reports if you have any :wink:

I’m not sure how big the impact of multiplatform really is. I can’t imagine it’s that big. Of cause it is more work to design a system so that it can work on any platform using just a few number of platform hooks that need to be implemented for each platform. I however don’t believe that it’s more work than writing the system in multiple languages. But then I don’t know the design of your legacy data classes you have to work with.


#5

Yes, if starting from scratch I think it would be well worth it to define the data object model in Kotlin and carefully trace the more complex data types through to the end result as used by swift to be sure the behaviour on ios was as intended. it would be more work up front, but way less work once changes and evolution of the original apps began.


#6

It sounds like your description is lacking some layers of abstraction with its own transfer object types in each layer.

The common module can have common model types. The IOS module can have its ios model types, with converters between the model types.


#7

Good Point.

I already have manually converted Swift versions of the data classes which i can put into the Shared project iosMain subdir as actuals,
and I can put the java versions into the Shared project androidMain as actuals

and then just define expects in the commonMain for the classes used as occasional method parameters in my MVP common business logic implementations, and from what I have seen so far, that should (might) work.

Without having the java-> Kotlin-> objc-> used by Swift conversion chain with potential problematic type discrepancy issues

thanks