How to create a shared library from Java code

Mitsunori Komatsu
2 min readJul 17, 2018

--

As you may know, GraalVM’s native-image command is capable of creating a shared library from Java code

An SVM image can be built as a standalone executable, which is the default, or as a shared library by passing --shared to native-image

https://github.com/oracle/graal/blob/master/substratevm/README.md#images-and-entry-points

It sounds very useful to call a Java library from C or something. Let’s try!

First, write a static method in Java:

Static methods that will be converted to a shared library need to have a specific annotation and accept Isolate/IsolateThread as the first argument.

Next, compile the class using javac

$ javac org/komamitsu/foobar/SharedFooBar.java
$

Then, create a shared library using native-image command

$ native-image --shared -H:Name=libfoobar
Build on Server(pid: 66099, port: 64714)
classlist: 250.62 ms
(cap): 1,967.46 ms
setup: 2,497.16 ms
(typeflow): 3,190.13 ms
(objects): 1,842.08 ms
(features): 43.43 ms
analysis: 5,209.07 ms
universe: 216.93 ms
(parse): 1,053.24 ms
(inline): 561.35 ms
(compile): 3,761.77 ms
compile: 5,768.34 ms
image: 890.81 ms
write: 1,345.32 ms
[total]: 16,224.53 ms
$ ls -ltr
total 10328
drwxr-xr-x 3 komamitsu staff 102 Jul 16 21:43 org
-rw-r--r-- 1 komamitsu staff 334 Jul 17 22:05 libfoobar_dynamic.h
-rw-r--r-- 1 komamitsu staff 310 Jul 17 22:05 libfoobar.h
-rwxr-xr-x 1 komamitsu staff 5227120 Jul 17 22:05 libfoobar.dylib
-rw-r--r-- 1 komamitsu staff 3035 Jul 17 22:05 graal_isolate_dynamic.h
-rw-r--r-- 1 komamitsu staff 2939 Jul 17 22:05 graal_isolate.h
$

Of course, we need to write main function in C

This program does:

  • Create isolate
  • Call a function in the shared library that is generated from the Java static method. You can find the method name in libfoobar.h created by native-image --shared
  • Release the isolate

Let’s compile the C code with the static library and execute it.

$ cc -Wall '-Wl,-rpath,$ORIGIN' -I. -L. -lfoobar main.c
$ ./a.out
42 + 13 = 55

It works!

(Update: appended an example to show how to receive String arguments)

--

--

Responses (2)