giovanniberti / robusta

Easy interop between Rust and Java
MIT License
335 stars 16 forks source link

Issue with mapping Java class fields of type `byte[]` to a `Field` with type `Box<[u8]>` #69

Open David-Petrov opened 8 months ago

David-Petrov commented 8 months ago

I'm trying to map a Java class having a byte[] field to a struct in rust in the way described in the README.md, but I stumble upon a weird issue with error types somewhere in the underlying trait derivations.

For the simplest possible reproduction:

  1. Fresh clone of the repo.
  2. In the rust example, change the field type here from String to Box<[u8]>.
  3. We won't even need to change the other parts of the example accordingly, since at this point as a diagnostic in VSCode exactly under the macro symbol here appears the above-mentioned compilation error:
    
    type mismatch resolving `<*mut _jobject as TryFrom<JValueWrapper<'_>>>::Error == Error`
    expected `Error`, found `Infallible`
    field.rs(55, 82): required by a bound in `Field::<'env, 'borrow, T>::field_try_from`

the trait bound *mut _jobject: From<JValueWrapper<'_>> is not satisfied required for JValueWrapper<'_> to implement Into<*mut _jobject> required for *mut _jobject to implement TryFrom<JValueWrapper<'_>>

field.rs(55, 53): required by a bound in Field::<'env, 'borrow, T>::field_try_from the trait bound JObject<'_>: From<*mut _jobject> is not satisfied the following other types implement trait From<T>: <JObject<'a> as From<JThrowable<'a>>> <JObject<'a> as From<JClass<'a>>> <JObject<'a> as From<JString<'a>>> <JObject<'a> as From<JMap<'a, 'b>>> <JObject<'a> as From<JList<'a, 'b>>> <JObject<'a> as From<JByteBuffer<'a>>> <JObject<'a> as From<&'a GlobalRef>> <JObject<'a> as From<&'a AutoLocal<'a, '_>>> required for *mut _jobject to implement Into<JObject<'_>> required for JValue<'_> to implement From<*mut _jobject>



I tried investigating this myself, but to little avail. I suspect one of two things:
1. A rather trivial to fix issue with resolving imports, i.e. a simple `use` statement of a trait implementation might fix this;
2. I'm misunderstanding the intent behind the usage of the [conversion table](https://github.com/giovanniberti/robusta/tree/fc5007c553bcb27dfb8673fbcad32febde583533?tab=readme-ov-file#conversion-table) within fields. Perhaps this has to do with the mentioned [type conversion limitations](https://github.com/giovanniberti/robusta/tree/fc5007c553bcb27dfb8673fbcad32febde583533?tab=readme-ov-file#limitations) or the [FIXME note here](https://github.com/giovanniberti/robusta/blob/fc5007c553bcb27dfb8673fbcad32febde583533/src/convert/field.rs#L83).

Funnily enough, if we try to convert a Java field of type `ArrayList<byte[]>` as a `Vec<Box<[u8]>>`, everything compiles and works. I find this strange, since the `TryFromJavaValue` implementation for `Vec<T>` generically relies on `T` being convertible from a java value. So for now, a feasible solution is to simply hold a list with a single value.

Any feedback on the matter would be welcome, I though this is worth mentioning as an issue. :)
uvlad7 commented 7 months ago

@David-Petrov, it works in #50 version. I actually don't understand why it doesn't work in the master version, a lot of changes were made, but you suggestions aren't true.

UPD: It's because TryFromJavaValue::Source and TryIntoJavaValue::Target were primitive jbyteArray, alias for jobject, not wrapped JObject, and this type must be infallibly convertible into JValue and fallibly - from JValueWrapper:

    <T as TryFromJavaValue<'env, 'borrow>>::Source: TryFrom<JValueWrapper<'env>, Error = JniError>,
    JValue<'env>: From<<T as TryIntoJavaValue<'env>>::Target>,

Note, that type for byte[] was changed from Box<[u8]> to Box<[i8]> to be consistent with byte -> i8 conversion, see the issue in the jni-rs repo. Now I see it can be inconvenient when working with String <-> byte[] on the Java side and str <-> &[u8] on the Rust side, but that's it, bytes are unsigned in rust and signed in java.

AndreiCravtov commented 3 months ago

whats the status on this currently? I cant seem to figure out what to do