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

Passing Integer from Java to Rust panics #41

Closed
aon opened this issue Dec 1, 2022 · 11 comments
Closed

Passing Integer from Java to Rust panics #41

aon opened this issue Dec 1, 2022 · 11 comments

Comments

@aon
Copy link

aon commented Dec 1, 2022

Hi! I'm having an issue with the library (which is great btw). I'm unable to pass Integer from Java to Rust, as it panics. I'm running this on Android btw, in an emulator on a Macbook Pro m1, with Java 11.

This are some simplified versions of the code I'm using:

public class Rust {
    private static native Instance fnSign(Instance<String> message, Instance<String> key, Instance<Integer> parties, Instance<String> address);

    public Signature sign(String message, String key, String address) {
        Integer parties = Integer.valueOf(55);
        Instance instance = fnSign(
                Java2RustUtils.createInstance(message),
                Java2RustUtils.createInstance(key),
                Java2RustUtils.createInstance(parties),
                Java2RustUtils.createInstance(address));
        return Java2RustUtils.getObjectCasted(instance);
    }
}
#[call_from_java("expo.modules.multipartyecdsa.Rust.fnSign")]
fn sign(
    message: Instance,
    key: Instance,
    parties: Instance,
    address: Instance,
) -> Result<Instance> {
    let jvm = Jvm::attach_thread()?;

    let message: String = jvm.to_rust(message)?;
    let key: String = jvm.to_rust(key)?;
    let parties: i32 = jvm.to_rust(parties).unwrap();
    let address: String = jvm.to_rust(address)?;

    let signature = Signature {
        r: format!("message: {}, key: {}, address: {}", message, key, address),
        s: format!("parties: {:?}", parties),
        v: 1,
    };

    let ia = InvocationArg::new(&signature, "expo.modules.multipartyecdsa.Signature");
    let instance = Instance::try_from(ia)?;
    Ok(instance)
}

Something interesting that happens is that if I pass it as an array int[] it works.

If you have any further thing I can try or if you need any other information I'm all ears. Thanks!

@astonbitecode
Copy link
Owner

Thanks for the report.

Do you have any logs to share? Is the panic visible in logcat?

@aon
Copy link
Author

aon commented Dec 2, 2022

Yes! They're visible. Here is the logcat file, the panic starts on line 243.

Here's a screenshot of android studio debugger in case it's useful:
Screenshot 2022-12-02 at 10 11 58

@astonbitecode
Copy link
Owner

It seems that the primitive int returned from Integer.intValue() during the to_rust call, is not compatible with the i32 in Rust... Maybe the NDK you compile with does not fit the underlying Android version?

Here are some questions that could be helpful to resolve your issue:

  • Which NDK version do you use?
  • What is the target you build Rust against? armv7, arm64, or something else? Is this compatible with the device/emulator?
  • How do you link the cargo target (which linker do you use)?

As a workaround, you could use the to_rust_deserialized instead of to_rust. This way, the Integer will be sent to Rust serialized and will be deserialized in Rust, avoiding type incompatibilities between Rust and Java (with the performance penalties of deserialization, of course).

@aon
Copy link
Author

aon commented Dec 2, 2022

Ok I can confirm using to_rust_deserialized works correctly.

Regarding your questions:

  • NDK v21.4.7075529
  • I'm building against arm64, specifically aarch64-linux-android.
  • I'm using the provided clang from android, this is my config.toml file:
[build]
rustflags = "-L native=/Users/agustin/work/coinfabrik/expo-multi-party-ecdsa/rust/android/gmp/arm64-v8a"

[env]
CC_aarch64-linux-android = "/Users/agustin/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android30-clang"
AR = "/Users/agustin/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-ar"

[target.aarch64-linux-android]
ar = "/Users/agustin/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-ar"
linker = "/Users/agustin/Library/Android/sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android30-clang"

I tried changing my NDK to the latest version available (25.1.8937393) but the AR aarch64-linux-android-ar doesn't seem to exist anymore, and the provided llvm-ar doesn't work as the linker fails compilation on rust saying -lgcc not found.

BTW I really apprecciate you helping me debug this, I know it might not have anything to do with your library but you're doing it anyway so thanks.

@aon
Copy link
Author

aon commented Dec 2, 2022

OK it seems I was using the ndk v21 because rust has issues with higher versions (rust-lang/rust#85806). I'll also try to change the project name (and library) because it was called libandroid.so and it seems this conflicts with the android framework library as shown here https://github.com/rust-windowing/android-ndk-rs.

@aon
Copy link
Author

aon commented Dec 3, 2022

Changing the project name did nothing. So if you think of anything else I'm happy to try.

@astonbitecode
Copy link
Owner

Thanks for the info.

I will try to reproduce it and will comment any findings

@astonbitecode
Copy link
Owner

Ok I was able to reproduce it using Java 11, android-ndk-r22b and aarch64.

It seems that there was a behavior change somewhere between and the CallObjectMethod does not return any more the expected in Android. I will change the jni calls to the appropriate ones for creating primitives and will commit the fix soon.

@astonbitecode
Copy link
Owner

After the last commit, my tests run successfully in Android.

Can you please verify in your environment as well before closing this?

Thanks

@aon
Copy link
Author

aon commented Dec 14, 2022

It's working now! Thank you for the help and quick debugging.

@astonbitecode
Copy link
Owner

Good! Thanks for reporting

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants