Hey, guys. I need to be able to access some Java A...
# kotlin-native
u
Hey, guys. I need to be able to access some Java API (classes from
java.security
to be more detailed) from Kotlin code that is compiled with Kotlin/Native into binary (shared library used on android). Any suggestions on how i can achieve it? In regular java code i had to write JNI glue code for this i guess, wondering if i can achieve it more in more elegant way with Kotlin
g
JNI is the only way
👍 1
t
Could you folks elaborate a bit on that? Afaik we can use JNI to access native code from java, but how does that help in the other direction to access java code from native 🤔
👍 1
g
You can write JNI code that exposed as C API, so it can be called from K/N with C Interop
JNI is 2-way thing
u
@gildor so there is still need to write JNI code in that new approach? Yeah, i know on how to call java from jni c++: find class, find method, prepare args, call with jni func, etc. However it seems to be inconvenient and lot’s of boilerplace code
g
sure
JNI is pain
There are some facilities in K/N that simplify this, but it’s just internal tool of K/N, nothing public to simplify this use case combination of K/N and Kotlin JVM is not different from C/C++ and Kotlin JVM/Java, the same interop problem, and only JNI
u
I’ve been thinking about it and found that Kotlin could use it’s
expect/actual
approach. If we mark that expected class with some custom annotation like
@JavaFromNative
it (new required interop tool) can generate that JNI glue code file that calls java impl from native impl. The interfaces are 100% compatible. Afraid it can work for primitive types only, but anyway
g
Yes, in theory it’s of course possible on some level, to have some interop between Kotlin JVM and K/N, I would happy to have it, but nothing like this is available at least as final solution
u
@gildor thanks for your input
@gildor But working at anything at that direction or no plans on this?
g
Last time when I asked K/N team about this they mentioned that they have own tools for that, but they do not plan nothing specific for this use case
u
hmm, sounds like something at least. No links to repos?
g
Maybe if more people want this they will work, who knows, I would create an issue on Kotlin issue tracker and you could add your use case there
Not sure that I can find it now
u
Honestly i don’t think it should be too complicated, at least for primitive types. I think i will take a look
Without objects support is too limited for real life usage imo
You cannot even use List<T>
u
tend to agree, but i can see some use cases. I think List in general can’t but some concrete impls from stdlib can,
ArrayList
seems to be available in both /jvm and /native, right?
but yeah, needs some time to investigate, since it’s again objects, not primitives
g
it available, but if you cannot pass it between platfroms it still useless
if you can, than you have no limitation about “primitive types”
t
Thanks for all the input, sounds really interesting 👍
u
you (plugin or compiler plugin) can generate code that will create platform classes from what is passed
g
yes, one more interop level, nobody says that it’s impossible, problem that nobody works on it and do not concider as important use case, this is why I recommend to create a feature request with your use case
u
i will, thanks for advice
also i think i will try to write smth as i really need it
unless somebody comes with anything existing (or at least conceptually the same impl)
g
for adhoc implmenetation usually easier to write JNI manually or generate it than write real K/N to Kotlin JVM interop
u
i agree, but in long-time run the classes will be changed, another classes will be added - i can really see value in such tool. >“or generate it”. As we’ve just discussed there is no “generation tool” for such case, isn’t it?
g
not for K/N as I know, but there is a bunch of tools for JVM to generate JNI
u
i know about few frameworks to call native from java (including jna), not vice versa. Can you suggest any that suits this case: generate native code (c/c++) to call java having java classes from native?
g
nope
u
thanks anyway
Any input on this is still very appreciated, anybody?
just a fast googling
u
Fast googling is good. However it’s valuable to know people experience
s
Why do you need to mix Kotlin/Native and Kotlin/JVM in the same application?
g
Our case, because we use native only API for high performance audio, which available only in NDK (OpenSL and AAudio)
also there are some other use cases, like usage of native heap (see https://github.com/facebook/fresco), usage of other native libraries (see https://github.com/Yalantis/uCrop)
u
@svyatoslav.scherbina Hi! I can share some details. There are apps [large and old] that are mostly written in C++. So usually they are compiled as huge shared libs wrapped into android code and platform UI added on the top. Eg. Chromium, games, etc. Some Photoshops, CADs, image/sound editors come into my mind too, It’s not rare case btw - most performance-critical or low-level hardware apps with legacy code are written that way
g
Why do you need to mix Kotlin/Native and Kotlin/JVM in the same application
One more thing, even if most of your application is Native, it’s hard to do everything on native side, you have very limited access to Android API from native, so you still want to use Android SDK APIs (just to configure application, launch native part, control notifications, get access to application properties etc) and for this you need JVM language and good interop would be very helpful
s
usage of native heap
So you need a fancy wrapper for
sun.misc.Unsafe
here.
usage of other native libraries
Support for using C libraries in Kotlin/JVM would be enough for this.
There are apps [large and old] that are mostly written in C++. So usually they are compiled as huge shared libs wrapped into android code and platform UI added on the top. Eg. Chromium, games, etc. Some Photoshops, CADs, image/sound editors come into my mind too, It’s not rare case btw - most performance-critical or low-level hardware apps with legacy code are written that way
What makes you think that Kotlin/Native should suitable for this?
g
So you need a fancy wrapper for
sun.misc.Unsafe
here.
Not really
Support for using C libraries in Kotlin/JVM would be enough for this.
Yes, it one of the options, but isn’t K/N is better candidate for this? And interop between Kotlin looks as better than write completely new C interop for JVM, but I’m not sure
s
Not really
Why so?
And interop between Kotlin looks
the hardest solution for this problem.
completely new C interop for JVM
Is internally available from the very beginning of Kotlin/Native project.
g
I see
u
@svyatoslav.scherbina > “What makes you think that Kotlin/Native should suitable for this?” We have some part of functionality that can work as standalone product (with minor wrapping) and should be able to embedded into different products. We want to get benefit from Kotlin/JVM and Kotlin/Native and write our functionality in Kotlin. One of products (use cases) is basically Chromium, which has large part written in C++. It has to be able to call our code. So the idea is to compile our kotlin code into binary (shared library) with K/N and call it from Chromium C++. However in this case we still have to access java.security.* so we need bridging. The alternative is to compile it to JVM and write jni to access our part from C++ but it again goes to jni to be written (or generated).
@svyatoslav.scherbina For me it sounds as really good opportunity: to generate C++ platform impl that automatically calls same JVM platform impl. The interface is 100% same and it’s clear how the call code should be generated. Though i can see some non-primitive types difficulties
s
That would make sense if interoperability between Kotlin/Native and Kotlin/JVM was available. But I have to repeat that proper interoperability here is quite difficult to implement.
However in this case we still have to access java.security.* so we need bridging
Why not use an equivalent native library?
u
we could use libcrypto or anything but it will increase apk size and it will require separate compilation per arch that we’d like to avoid