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

Cannot Pass Vec as a Parameter to Java Function #122

Open
ktseytlin opened this issue Feb 26, 2024 · 2 comments
Open

Cannot Pass Vec as a Parameter to Java Function #122

ktseytlin opened this issue Feb 26, 2024 · 2 comments

Comments

@ktseytlin
Copy link

Hi!

Creating this ticket to track using Vec <-> List / ArrayList for function parameters.

Expectation: I can pass in a list of arguments (of any type) to a Java function via Duchess

Current: I can pass in a Vec<T> to a Rust function if it is a parameter for a Java Record. I cannot pass Vec<T> directly as parameters.

See code below for reproduction.

See compiler output for what I'm seeing for the two cases: test_with_string_array and test_with_string_list.


Java side:

import java.util.List;

public class KerenDemo {

    public void test_with_string_array(String[] x) {
        System.out.println(x);
    }

    public void test_with_string_list(List<String> x) {
        System.out.println(x);
    }

    public void test_record_param_is_string_list(StringListRecord input) {
        System.out.println(input.records());
    }
}
import java.util.List;

public record StringListRecord(
    List<String> records
) { }

Rust Side:

duchess::java_package! {
    package demo;

    class KerenDemo { * }
    class StringListRecord { * }
}

#[derive(Clone, Debug, PartialEq, duchess::ToJava)]
#[java(demo.StringListRecord)]
pub struct StringListRecord {
    pub records: Vec<String>,
}

pub struct DemoClient {
    client: duchess::Global<demo::KerenDemo>,
}

impl RustKerenDemo {
  pub fn new() -> Arc<Self> {
    Arc::new(DemoClient { client: Self::build_client().unwrap() })
  }

    fn build_client() -> duchess::GlobalResult<Global<demo::KerenDemo>> {
        duchess::Jvm::builder().launch_or_use_existing().unwrap();
        metering::KerenDemo::new().global().execute()
    }

  pub fn does_not_work (self: Arc<Self>) {
         tokio::task::spawn_blocking(move || {
            duchess::Jvm::attach_thread_permanently().unwrap();
            self.client
                .test_with_string_list(vec!["Some signature".into()])
                .execute()
                .unwrap();
        });
  }

  pub fn does_not_work_2 (self: Arc<Self>) {
         tokio::task::spawn_blocking(move || {
            duchess::Jvm::attach_thread_permanently().unwrap();
            self.client
                .test_with_string_array(vec![String::from("Some signature")])
                .execute()
                .unwrap();
        });
  }

  pub fn this_works(self: Arc<Self>) {
        let record = StringListRecord {
            records: vec!["Some signature".into()],
        };
         tokio::task::spawn_blocking(move || {
            duchess::Jvm::attach_thread_permanently().unwrap();
            self.client
                .test_record_param_is_string_list(&record)
                .execute()
                .unwrap();
        });
  }
}

Compiler output for the two functions above where it does not work:

   --> src/lib.rs:125:41
    |
125 |                 .test_with_string_array(vec![String::from("Some signature")])
    |                  ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `duchess::JvmOp` is not implemented for `Vec<std::string::String>`
    |                  |
    |                  required by a bound introduced by this call
    |
    = help: the following other types implement trait `duchess::JvmOp`:
              bool
              char
              i8
              i16
              i32
              i64
              u16
              f32
            and 192 others
    = note: required for `Vec<std::string::String>` to implement `duchess::IntoJava<Array<duchess::java::lang::String>>`
note: required by a bound in `ViewAsKerenDemoObj::<J, N>::test_with_string_array`
   --> src/lib.rs:14:1
    |
14  | / duchess::java_package! {
15  | |     package demo;
16  | |
17  | |     class KerenDemo { * }
18  | |     class StringListRecord { * }
20  | | }
    | |_^ required by this bound in `ViewAsKerenDemoObj::<J, N>::test_with_string_array`
    = note: this error originates in the macro `duchess::java_package` (in Nightly builds, run with -Z macro-backtrace for more info)
@nikomatsakis
Copy link
Member

So, the short version is that you ought to call .to_java for the arguments to convert them into Java:

 pub fn does_not_work (self: Arc<Self>) {
         tokio::task::spawn_blocking(move || {
            duchess::Jvm::attach_thread_permanently().unwrap();
            self.client
                .test_with_string_list(vec!["Some signature".into()].to_java()) // <-- 
                .execute()
                .unwrap();
        });
  }

Does that work?

@nikomatsakis
Copy link
Member

nikomatsakis commented Jul 16, 2024 via email

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