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

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

Open
David-Petrov opened this issue Mar 8, 2024 · 2 comments

Comments

@David-Petrov
Copy link

David-Petrov commented Mar 8, 2024

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 within fields. Perhaps this has to do with the mentioned type conversion limitations or the FIXME note here.

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. :)

@David-Petrov David-Petrov changed the title Box<[u8]> doesn't work for mapping Java class fields of type byte[] Issue with mapping Java class fields of type byte[] to a Field with type Box<[u8]> Mar 8, 2024
uvlad7 added a commit to uvlad7/robusta that referenced this issue Mar 19, 2024
@uvlad7
Copy link
Contributor

uvlad7 commented Mar 19, 2024

@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
Copy link

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

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

3 participants