Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JNI can't find some Kotlin functions for SDK 24-26 #531

Open
4 of 5 tasks
jpudysz opened this issue Feb 10, 2025 · 10 comments · Fixed by #534
Open
4 of 5 tasks

JNI can't find some Kotlin functions for SDK 24-26 #531

jpudysz opened this issue Feb 10, 2025 · 10 comments · Fixed by #534
Labels
nitro-core Issue is related to the Nitro Modules core runtime/C++ codebase

Comments

@jpudysz
Copy link
Contributor

jpudysz commented Feb 10, 2025

What's happening?

Hey,

for older Android SDKs 24-26 JNI struggles to get class method. It throws error that there is no such method, which is obviously not true. It works fine for SDK greater than 26+.

I was able to reproduce it locally, but can't with Nitro example.
I use C++ bindings to store C++ lambda on Kotlin side. I'm using it for sync callbacks.

Removing private from registerPlatformListener_cxx fixes the issue.

Reproduceable Code

void JHybridNativePlatformSpec::registerPlatformListener(const std::function<void(const std::vector<UnistyleDependency>& /* dependencies */, const UnistylesNativeMiniRuntime& /* miniRuntime */)>& callback) {
    static const auto method = _javaPart->getClass()->getMethod<void(jni::alias_ref<JFunc_void_std__vector_UnistyleDependency__UnistylesNativeMiniRuntime::javaobject> /* callback */)>("registerPlatformListener_cxx"); // <- crashes here
    method(_javaPart, JFunc_void_std__vector_UnistyleDependency__UnistylesNativeMiniRuntime_cxx::fromCpp(callback));
  }

Relevant log output

Exception in HostObject::get for prop 'Unistyles': java.lang.NoSuchMethodError: no non-static method "Lcom/unistyles/NativePlatformAndroid;.registerPlatformListener_cxx

Device

Android Emulator with SDK 24-26

Nitro Modules Version

0.22.1

Nitrogen Version

0.22.1

Can you reproduce this issue in the Nitro Example app here?

No, I cannot reproduce the issue in the Example app

Additional information

@jpudysz jpudysz added the nitro-core Issue is related to the Nitro Modules core runtime/C++ codebase label Feb 10, 2025
@mrousavy
Copy link
Owner

mrousavy commented Feb 10, 2025

Hm, I wouldn't understand why this suddenly fails. You can call private methods through JNI, that shouldn't make a difference at all.
In fact, I am doing it in NitroExample (in the react-native-nitro-image TestObject) quite a lot, and I even have an example that is almost identical to yours - a function with a callback:

@DoNotStrip
@Keep
private fun callCallback_cxx(callback: Func_void): Unit {
val __result = callCallback(callback)
return __result
}

That's private and can be called from C++/JNI just fine.

@mrousavy
Copy link
Owner

mrousavy commented Feb 10, 2025

Why are you saying SDK 24-26 explicitly - does this not happen on minSdk 26 or higher?

Ah - so it works on minSdk 26+... That is even more weird, lol.

@mrousavy
Copy link
Owner

@jpudysz can you add @JvmName("registerPlatformListener_cxx") to your private func to see if that makes it work?

@mrousavy
Copy link
Owner

Potential fix: #534

@mrousavy
Copy link
Owner

And the last thing you can try is to add a @DoNotInline annotation to your private fun. See if that changes anything.

Appreciate your help here

@mrousavy
Copy link
Owner

I just merged this - but pls still try if @JvmName OR @DoNotInline work for you.

@jpudysz
Copy link
Contributor Author

jpudysz commented Feb 11, 2025

@JvmName + private didn't work.

same for @DoNotInline. It's getting weird. No idea why it fails for older SDKs.

@mrousavy
Copy link
Owner

Ah, shit.

@mrousavy mrousavy reopened this Feb 11, 2025
@mrousavy
Copy link
Owner

I would need to reproduce this here in the example app, can I just set minSdk to 24 and it will be reproduceable?

@jpudysz
Copy link
Contributor Author

jpudysz commented Feb 11, 2025

You can repro it with my example on main branch. You can use expo-example. Adding private in generated files + prebuilding causes the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
nitro-core Issue is related to the Nitro Modules core runtime/C++ codebase
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants