astonbitecode / j4rs

Java for Rust
Apache License 2.0
632 stars 35 forks source link

Borrow checker problem #76

Closed TropicalDog17 closed 1 year ago

TropicalDog17 commented 1 year ago

Hi, I want to call Java library about NLP from Rust side. The original Java code is this

        VnCoreNLP pipeline = new VnCoreNLP(annotators); 

        String str = "Some Text"; 

        Annotation annotation = new Annotation(str); 
        pipeline.annotate(annotation); 
        System.out.println(annotation.toString());

And I want to use Rust to call from this Java library. I have tried this

...
    let i = InvocationArg::try_from(annotators.as_slice())?;
    let pipeline = jvm.create_instance("vn.pipeline.VnCoreNLP", &[i])?;
    let s = InvocationArg::try_from(String::from("Some Text"))?;
    let annotation = jvm.create_instance("vn.pipeline.Annotation", &[s])?;
    let i_annotation = InvocationArg::try_from(annotation)?; // Value moved here
    let _ = jvm.invoke(&pipeline, "annotate", &[i_annotation]);
    let string_instance = jvm.invoke(&annotation, "toString", &Vec::new()); // Value used after move

But Rust doesn't allow me to do this, since annotation is moved in the try_from line. Any suggestion/workaround for this? Am I missing something important? Thank you.

astonbitecode commented 1 year ago

Hi,

you could clone the annotation before creating the i_annotation.

Something like:

let annotation = jvm.create_instance("vn.pipeline.Annotation", &[s])?;
let annotation2 = jvm.clone_instance(&annotation)?;
TropicalDog17 commented 1 year ago

@astonbitecode I had no idea about the clone_instance method. Thanks a lot for your speedy help! It works like a charm, but I wonder how the clone_instance work,

let annotation = jvm.create_instance("vn.pipeline.Annotation", &[s])?;
let annotation2 = jvm.clone_instance(&annotation)?;

Does these two instances connected to each other, since the Java code appears to modify the annotation in place. But when I pass the annotation to the pipeline, annotation2 is modified as well.

        Annotation annotation = new Annotation(str); 
        pipeline.annotate(annotation);
astonbitecode commented 1 year ago

Well, I must admit that clone_instance is not the perfect name...

From the Java point of view, a clone is the creation of a new instance, independent from the original one. From the Rust point of view, a clone_instance is actually the creation of a new Instance, which is a reference to the initial Instance.

Please let me know if you can propose better naming...

TropicalDog17 commented 1 year ago

From the Rust point of view, a clone_instance is actually the creation of a new Instance, which is a reference to the initial Instance.

I guess you should consider including this in the documentation for better clarity. Anyway, thanks a lot for your response.

astonbitecode commented 1 year ago

I am planning to create wiki pages containing such pitfalls / things that need more explanation.

Hopefully soon...

Thanks for reporting