Skip to main content

Getting Started with Java


To use the library, we recommend you update Rust to the latest stable version $ rustup update stable. Nightly should be fine but some changes might not be compatible.

  • Download or clone the repository
$ git clone
  • A valid C compiler
  • Rust installation on your path
  • Gradle v4 or higher or Maven installed

Preparing your work environment

In order to build with the Java bindings, you need the following two parts:

  1. Java classes containing native methods which call C code. (.jar)
  2. JNI bindings linking Rust to C, and then C to java native methods (.so , .dll or .dylib depending on your system)

Step 1: Linking the Java file (Jar)


Installing the jar on your system

mvn install:install-file -Dfile=/path/to/ -DgroupId=org.iota.client -DartifactId=native -Dversion=1.0 -Dpackaging=jar 

Adding the dependency to POM



With a pre-made jar

  • Point to the JAR in build.gradle dependencies section using implementation files("native.jar")

Building the jar through gradle in creates the jar at

Directly pointing to the project

  • Uncomment the lines in settings.gradle, then:
  • Change settings.gradle to point to the \native project inside\bindings\java, so we can load the Java files
  • Add implementation project(':native') to the dependencies section of your build.gradle (and comment implementation files("native.jar") if you have it)

Step 2: Adding the native library

This file can be found at after building the bindings with cargo build --release in the folder. We will call this file iota_client for the purpose of this README.


Adding the folder to your PATH is the easiest way to ensure it is available.


  1. Change to your home directory. cd $HOME.
  2. Open the .bashrc file.
  3. Add the following line to the file: export PATH=/path/to/iota_client:$PATH.
  4. Save the file and exit. Use the source command to force Linux to reload the .bashrc


  1. Open the Start Search, type in “env”, and choose “Edit the system environment variables”
  2. Click the “Environment Variables…” button.
  3. Under the “System Variables” section (the lower half), find the row with “Path” in the first column, and click edit.
  4. The “Edit environment variable” UI will appear. Click “New” and type in the new path: /path/to/iota_client
  5. Dismiss all of the dialogs by choosing “OK”. Your changes are saved!


  1. Open up Terminal.
  2. Run the following command: sudo nano /etc/paths.
  3. Enter your password, when prompted.
  4. Go to the bottom of the file, and enter the path you wish to add.
  5. Hit control-x to quit.
  6. Enter “Y” to save the modified buffer.


We need to make sure the file is added to java.library.path before building or running. To do this, we add/update the section below to our pom.xml

The ${basedir} means we need to place the iota_client file in the base of our repo. (Where your pom.xml is) Alternatively, you can replace ${basedir} with an absolute path to the file: /path/to/iota_client



Modify build.gradle variable iotaLibLocation to the location of iota_client.

Step 3. Building your app


Run mvn compile to build.

Run mvn exec:java -Dexec.mainClass="org.example.ExampleApp" to run. (You can also add the mainclass to your pom using the exec-maven-plugin plugin)

Run mvn test to specifically run the test.


Run gradle build to build.

Run gradle run to run. (linking directly to the for jar triggers a rebuild every time)

Run gradle test to specifically run the test.


As the API is made to be as close as possible to the rust API, the most up to date documentation can be found here, until a pure Java version is made.

YOu can also generate more up-to-date documentation by compiling it yourself. Instructions can be found [here]](

The java methods are made to almost 1:1 correspond to rust version. Difference beeing the naming convention (Rust beeing snake_case, java camelCase)


This example fetches node information

use iota_client::Client;

async fn main() {
let iota = Client::builder() // Crate a client instance builder

let info = iota.get_info().await.unwrap();
println!("Nodeinfo: {:?}", info);


Due to the fact that we are linking through C from Rust, there are a couple of limiting factors.

  • Classic builder patterns return a clone after each builder call since we can only pass back to C by reference in Rust
Builder builder1 = new Builder();
Builder builder2 = builder1.setValue(true);

// These are different instances, thus builder1 wont have the value set
assertNotEquals(builder1, builder2);