如何从 Ballerina 调用用户定义的非静态 Java 方法

How to invoke user defined non-static Java method from Ballerina

示例[1] 展示了如何调用 Java 方法。但就我而言,我需要从我自己的 class 调用我自己的方法。像这样

Hello.java

public class Hello {
    public String sayHello() {
        return "Hello . . .";
    }
}

hello_java.bal

import ballerina/io;
import ballerina/java;

function sayHelloJava() returns handle = @java:Method {
    name: "sayHello",
    class: "Hello"
} external;


public function main() {
    var txt = sayHelloJava();
    io:println(txt);
}

当我 运行 时,出现以下异常

Compiling source
        hello_java.bal
error: .::hello_java.bal:4:1: {ballerina/java}CLASS_NOT_FOUND 'Hello'
Running executables

Error: Could not find or load main class ___init

.class.bal 文件都在同一目录中

谁能告诉我在 ballerina 中调用 sayHello java 方法的正确语法。

您还可以详细解释一下 ballerina

中的 handle 关键字吗

[1] https://ballerina.io/v1-2/learn/by-example/invoke-java-methods.html

您可以参考 interop guide 以获取有关此的详细信息。

针对您的具体情况,请按照以下步骤操作:

  • 为您的 Hello class 创建一个 Java 项目并获取构建的 .jar 文件。
  • 同时创建一个新的 Ballerina 项目并在其中添加一个模块(假设该模块名为 hello)。
  • 在您的项目根目录中创建一个名为 javalibs 的目录,并将 .jar 文件复制到其中。
  • 您的项目目录类似于以下内容:

    .
    ├── Ballerina.lock
    ├── Ballerina.toml
    ├── javalibs
    │   └── hello-1.0-SNAPSHOT.jar
    └── src
        └── hello
            └── main.bal
    
  • 将以下条目添加到您的 Ballerina.toml 文件中:

    [platform]
    target = "java8"
    
       [[platform.libraries]]
       path = "./javalibs/hello-1.0-SNAPSHOT.jar"
       modules = ["hello"]
    
  • 您的 Ballerina 代码应如下所示:

    import ballerina/io;
    import ballerina/java;
    
    public type Hello object {
        public function sayHello() returns string? {
            return java:toString(sayHelloExtern());
        }
    };
    
    function sayHelloExtern() returns handle = @java:Method {
        class: "xyz.pubudu.Hello",
        name: "sayHello",
        paramTypes: []
    } external;
    
    
    public function main() {
        Hello h = new;
        io:println(h.sayHello());
    
        string? s = java:toString(sayHelloExtern());
        io:println(s);
    }
    
  • 现在您可以使用 ballerina run hello 运行 它应该打印 Hello . . .

1.2.0 版本中,引入了一个名为 bindgen 的新 CLI 工具,可以轻松为 Java API 生成 Ballerina 绑定,因此用户无需手动编写像我们上面所做的那样绑定。查看我上面链接的互操作指南以获取更多详细信息。

添加到@pubudu 的回答中,我只想展示如何在 Ballerina 中调用非静态 Java 方法。

由于您的 sayHello 方法是非静态方法,您需要在 ballerina 中使用 java:Constructor 注释创建 Hello class 的实例。

那么您的 sayHello 函数应该将创建的实例(从 java:Constructor 互操作函数返回的 handle 值)作为第一个参数。

您的 Ballerina 代码应如下所示:

import ballerina/io;
import ballerina/java;

function newHello() returns handle = @java:Constructor {
    class: "Hello"
} external;

function sayHello(handle helloObject) returns handle = @java:Method {
    class: "Hello"
} external;

public function main() {
    var helloObj = newHello();
    io:println(java:toString(sayHello(helloObj)));
}