We just recently open-sourced an early prototype of a library for interoperability between Java and Swift at GitHub - swiftlang/swift-java. Our goal is to make it possible to interoperate in both directions:
The library is a very early prototype of both directions, using macros and code generation for Swift → Java calling and the Foreign Function and Memory API (aka Project Panama) for Java → Swift. Everything about it is up for discussion and change. We’d love to talk through design ideas, use cases, and implementation sketches.
Speculation and dreaming:
Might this in fact open up possibilities in the future to develop Android apps in Swift, using swiftlang official support - using some UI framework built on top of Android for Swift
Fantastic work. Kudos to the entire team! C, Objective-C, Python, C++, and now Java interoperability.
Looking forward to see what we all can build on top of it. Java support was unexpected, but most wanted for me
Conversely, would it allow porting existing Mac or Android apps written in Java? I know of at least one application that's available on desktop and Android, but not iOS, because all of the logic is written in Java and would require a complete rewrite.
The fact that we may one day develop backend services with Spring Boot + Swift is making me supper happy and excited for what the future brings. Kudos to everyone involved with this project and thanks a lot for all of your efforts!
Out of curiosity: Is my understanding correct that it's not a big effort to try this out with Maven? The repository uses Gradle, which makes me wonder whether this was an arbitrary choice or were there some blockers which I do not foresee in switching to mvn as a build system.
It could. The JNI parts of the implementation should work on Android for Swift calling into Java libraries. Android doesn't support the newer Foreign Function & Memory APIs that we're using for Java calling into Swift, so we would need to bring up a JNI-based solution there to work on Android and older Java installations.
It was arbitrary. For primarily Swift code bases, I'd like us to make the library usable with SwiftPM. But if you're using Swift inside a mostly-Java ecosystem, integrating with both Gradle and Maven makes sense.
Nice, it'll be great to see some adoption of the libs so we can make sure it's ergonomic etc We're figuring out how and when to tackle android but it's certainly another very interesting use-case.
It was awesome seeing this announcement at the conference! I’d love to help out, and explore if we could extend this (in the future) to proper Kotlin bindings as well. My goal would be to eventually bring it to a place where it could be a more ergonomic alternative to Kotlin Multiplatform - really excited about the potential here!
Great to hear from you online as well! Was fantastic to catch up in person and I hope we can join efforts eventually over here
Please watch the repo and please feel free to pick up any of the pending issues or create new ones. Better interop with other JVM languages isn't a top priority, but if anyone in the community were to pick it up I'd be happy to support the work, so please stay in touch In the meantime there's a lot of work to be done with just plain Java/JNI/Panama
from my understanding, skip is a transpiler, it doesn't really makes interop between swift code and android code. It just rewrites all your swift code (and only a subset of the language is supported) to kotlin.
Awesome stuff! We are currently using an old C-library across our apps (Android/Java & Swift/iOS) for an internal network protocol. I would really love to write it in Swift with SwiftNIO instead. Would it technically be possible (in the future) to write a fully fledged cross-platform library (with SwiftNIO) for Android and Swift using the JNI approach?
Would definitely like to contribute in that direction, if possible!
I will be releasing a Swift 6 SDK bundle for Android this week, that should make it easy to cross-compile for Android from linux or macOS, by using the OSS toolchain.
Java is certainly… a… direction. I just have to assume that there is a team at Apple that really needs this feature. Can you share the details? What exactly are they doing? What is the "killer app"?
I assume that it is not Android, because that would take years, and (as far as I know) Apple has no interest in doing so - the famous Tim Cook quote: "buy your mother an iPhone". I expect that even after this project matures the Android part will be community supported.
I think it is more about tapping into the Java ecosystem for distributed computing:
interacting with the existing business logic - I assume that Apple has tons of existing Java/Scala code
avoiding the need to write a specific Swift driver for every library/protocol
Anyway, Swift goes in a slightly unusual direction with in-process FFI. This type of stuff is easy for JVM/.Net languages because they share the same runtime (C# and F# etc.). For Swift it means a lot of work for every supported language.
At the same time I think that the language is still lacking in more common scenarios. For example we use:
Node - because it is a web native
Python - best ecosystem, best solvers/math
Swift - fast, low memory, good concurrency
And then we try to combine them with:
protobuffs/gRPC
Docker compose - for example we use github.com/zedeus/nitter for Twitter. This is written in Nim, so we wrap it with Node webserver using the RSS endpoints.
Child process - thumbnail generation with ImageMagick etc. A bit more interesting example is that we use Signal for communication. For that we have a Node chat bot based on github.com/AsamK/signal-cli. This is essentially a signal-cli --config SOME_DIR jsonRpc with JSON stdin/stdout communication.
Problems:
protobuffs need binary compatible data. For example for Decimal we use IEEE-754 Decimal128 (BID stored as 2x UInt64): Node/Python use Intel library, Swift uses github.com/LiarPrincess/Oh-my-decimal with performance patches. It would be nice to have this kind of stuff already in Swift, I tried to contribute to the discussion, but as far as I know the topic died. (I never got an reply.)
Docker Compose needs working URLSession:
Swift 5.10 does not support async/await. Swift 6 does, but it was released just a few weeks ago, and servers are not the best environment for cutting edge software (compiler bugs etc…). As a rule we stay 1 compiler version behind.
WebSocket client crashes on Ubuntu 22.04 LTS (our deployment target) - we had to build our own on top of the NIO.
AFAIK you still can't write unit tests for downloads - I don't even remember how old this problem is.
There was a Subprocess proposal (the same code that you have inside of swift-java), but it was very very not great.
Seeing how Swift gets another interop I can't help but wonder: are we the outliers here? We use technologies that seem "common", but we face some pretty basic problems.
That should be technically possible, though the last time I looked into JNI was years ago. There are a lot of moving parts involved, and all of them would have to work 100% correct to make it production ready.
I think we are years away from getting there. Personally I would wait until Apple declares it "production ready" (as in: they are actually using it for business purposes), and then wait another year for a good measure.
If you haven't seen it already, there was a talk at ServerSide.swift about Java interoperability, referenced earlier in this thread.
Thank you for the feedback, but it belongs in other threads in relevant forum areas.
I think you're overstating the complexity of JNI by a large margin. JNI has been stable for longer than Swift has been in existence, and there are numerous binding generators and libraries for other languages. When we talk to folks using it, the primary concern isn't whether it works (it does), but about performance: having to pass Java objects around for anything that is non-primitive, and hold on to those Java objects from native code, can have unfortunate implications for Java GC performance.
We have lots of design decisions to get right to make the JNI-based interoperability work well, but aside from getting the right Swift-isms, this is well-trod territory.
Now, the jextract-swift direction, where we are using the new Foreign Function & Memory API? That's much more of a gamble, since they are newer APIs that are tying into Swift at a much lower level.