Ballerina offers a straightforward way to call existing Java code from Ballerina. Although Ballerina is not designed to be a JVM language, the current implementation, which targets the JVM, aka jBallerina, provides Java interoperability by adhering to the Ballerina language semantics.
Write Ballerina bindings
The bindgen
is a CLI tool that eases the process of generating Ballerina bindings for given Java APIs. This guide shows you how to use it. For more details on how the bindgen
tool works, see Bindgen Tool.
The Package layout explains how to package Java libraries (JAR files) with Ballerina programs to produce self-contained executable programs. When you generate bindings for a Java library using the Bindgen Tool, this part is already handled.
The Ballerina FFI explains how to write these bindings manually. It is also a useful section for those who want to understand the inner workings of calling Java from Ballerina and for those who want to customize the bindings generated by the Bindgen Tool.
Use the SnakeYAML Java library in Ballerina
SnakeYAML is a YAML parser for Java. This section describes how to use this library to parse a YAML document using Ballerina.
You develop a Ballerina program that parses the given YAML file and writes the content to the standard output.
Let's get started.
Step 1 - Write the Java code
It is recommended to always start by writing the Java code. It gives you an idea of the set of Java classes required to implement your logic. Then, you can use the bindgen
tool to generate Ballerina bindings for those classes.
The Java code below uses the SnakeYAML API to parse the given YAML file.
Note: This is not the most idiomatic way of writing the Java code for this scenario.
Here, you have used four Java classes:
org.yaml.snakeyaml.Yaml
java.io.FileInputStream
java.io.InputStream
java.util.Map
You can see them in the imported class list.
Tip: You are encouraged to generate Ballerina bindings for these four classes as a start.
Now, you create an environment for your Ballerina program.
Step 2 - Set up the Ballerina package
Info: This section assumes that you have already read Package layout.
Create a Ballerina package
Verify the package
Great! You are all set for the next step.
Add a sample YAML file
Copy the content below to a file named invoice.yml
in the package root directory.
Step 3 - Generate the Ballerina bindings
In this step, you will use the bindgen
tool to generate Ballerina bindings for the four classes that were listed in Step 1. If you want more information about the tool, see Bindgen Tool.
- The
-mvn
option specifies the Maven dependency of the Java library required to generate bindings. - The argument list specifies the Java class names.
The Bindgen Tool generates bindings for:
- the specified Java classes
- the Java classes exposed in the public APIs of all the specified classes
Before you move on to the next step, verify the generated code.
Step 4 - Write the Ballerina code
Now, you will use the generated bindings and write the Ballerina code, which uses the SnakeYAML library. You can develop the Ballerina code corresponding to the Java code below step by step.
Create the FileInputStream
The goal here is to create a new java.io.FileInputStream
instance from the filename. In Step 3, you generated bindings for the required Java classes. The following is the code snippet that does the job.
Here, FileInputStream
is the Ballerina class generated for the java.io.FileInputStream
class.
- Ballerina bindings for each Java package are mapped onto a separate Ballerina module by default. Therefore, you need to import them when using them inside other modules. Here, the
java.io
Ballerina module (mapping the corresponding Java package) is imported asjavaio
. However, if you wish to generate all the bindings inside a single directory, you can do so by using the[(-o|--output) <output-path>]
command option. - You can find functions that start with
newFileInputStream
in the generated code. Each such function creates a newjava.io.FileInputStream
instance. Ballerina does not support function overloading. Therefore, thebindgen
tool generates a separate Ballerina function for each overloaded method or constructor. Function names of the generated bindings will be improved in a future release. - All the public instance methods in the
java.io.FileInputStream
class are mapped to methods in the generated Ballerina class. For more details on how other Java class members are mapped into Ballerina bindings, see Bindgen Tool.
Next, you’ll handle the error
using a type guard.
Create the SnakeYAML entry point
The org.yaml.snakeyaml.Yaml
class is the entry point to the SnakeYAML API. The generated corresponding Ballerina class is Yaml
. The newYaml1()
function is mapped to the default constructor of the Java class. Import the org.yaml.snakeyaml
Ballerina module as snakeyaml
.
Load the YAML document
Use the org.yaml.snakeyaml.Yaml.load(InputStream is)
method to get a java.util.Map
Java instance from the given java.io.InputStream
. Since the Object
Ballerina class (the mapping of java.lang.Object
class) resides inside the java.lang
module, import it as javalang
.
Note: Even though you didn't explicitly generate the
java.lang.Object
class, it has been generated automatically since it is exposed through the public APIs of generated classes.
The org.yaml.snakeyaml.Yaml.load(InputStream is)
is a generic method. The Bindgen Tool does not support Java generics at the moment. That is why the corresponding Ballerina method returns a java.lang.Object
.
Print the returned map instance
You can print the content of the java.util.Map
instance in the standard out as follows.
Complete the code
Below is the complete code. You can replace the contents in main.bal
with the following code.
Build and run this code.
Now, you need to pass the YAML file name as the first argument.
The above sections explain how to use the bindgen
tool to generate Ballerina bindings for Java classes and how to use them.
For more information on various aspects related to Java interoperability in Ballerina, see Java interoperability.