Skip to content

swift-java does not work on Android API 28-30, due to missing JavaVM JNI symbols #419

@madsodgaard

Description

@madsodgaard

Currently, swift-java can crash runtime for Android API 28-30, if you try to use the JavaVirtualMachine class. This means that any JExtract generated sources (JNI mode) only works on API 31+, since we rely on JavaVirtualMachine.shared().environment().

This is due to the fact that Android first added official support for the JavaVM JNI functions, such as JNI_GetCreatedJavaVMs, in API 31+.
We rely on these methods for getting the active JavaVM, through for example JavaVirtualMachine.shared().

We have a shim for these JNI functions in https://github.com/swiftlang/swift-java/blob/main/Sources/CSwiftJavaJNI/AndroidSupport.cpp - this works on API 31+, because those Android versions have the libnativehelper.so. Previous versions did not. We cannot load libart.so or libdvm.so instead, since previous Android versions restricted dynamically loading these "private" libraries.

It seems like the recommended solution to this issue on Android, is to tap into JNI_OnLoad and store the VM from there. This would mean that we would need to update the shared VM at runtime:

private static let sharedJVM: LockedState<JavaVirtualMachine?> = .init(initialState: nil)

We need to figure out which library to dynamically load, that contains the JNI_OnLoad and can set the shared VM. My concern is since we already statically link the SwiftJava package (the generated sources depend on it), it would not be OK to just also dynamically load it on the Java side, but I am not sure.

An alternative solution could be (if this works in practice):

  1. Define a function in SwiftJava with @_silgen_name("_swift_java_setSharedVM"), which takes in a JavaVM and updates the shared one.
  2. Call that function in JNI_OnLoad from the already dynamically loaded SwiftRuntimeFunctions target to set the shared VM.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions