recipe № 023

Calling code from shared library (adapter pattern)

If you want to call method from shared library, there is nothing special here, when it comes to JNI. Calling shared methods from shared libraries is a typical sample of Adapter Pattern applied to Java calling native code. In this case, typically, you already have some sort of native code (written in C/C++/Fortran) and you want to make it available inside your Java code. In this case, JNI serves as adapter and allows to re-use already existing code base. Most common use case is very similar to picture below

In fact, there is not much to do from our side. All we need to do, is to make sure that we have shared library we want to link with and we have to make sure that library will be linked with shared library that contains JNI code. That’s all. Of course, there might be some issues here (I will show how to overcome them in some other place), but in general, that’s it.

Let’s say we have this special function we want call.

and we have created shared library that contains it

all we have to do, is to make sure that code we want to use from Java (e.g. this one)

is linked with the library that contains function we want to call.

That’s all. You can find full sample here: recipe № 023.

recipe № 022

running Java as daemon – main daemon’s loop in the C

Let’s say you want to run a daemon. And, for some reasons, you want to launch it using Java. For example, you have lots of preinitialization steps already written and code itself is Java based). In that case, execution schema will look like picture below

What we need here, is C based daemon stub. Code that will “daemonize” Java process.

Thanks to running code via JNI we can perform all daemon based setup:

      – setting custom SID for process,
      – changing dir to “/”,
      – closing standard streams: input, output, error – and attaching them to /dev/null,
      – executing endless loop.

Note that we will never get back to Java here. You can find another sample, where service part of daemon is executed in Java, here: recipe № 029. Full sample code for recipe recipe № 022 can be found at following location: recipe № 022 – sample code.

References:

– Robert Love, Linux System ProgrammingDaemons
– Devin Watson, Linux Daemon Writing HOWTO

recipe № 021

Calling code from another source file (adapter pattern)

If you want to call method from the source code you have, there is nothing special here, when it comes to JNI. You can simply put it inside shared library that contains JNI functions. This is a typical sample of Adapter Pattern applied to Java calling native code. In this case, typically, you already have some sort of source code (written in C/C++/Fortran) and you want to make it available inside your Java code. In this case, JNI serves as adapter and allows to re-use already existing code base. Most common use case is very similar to picture below

In fact, there is not much to do from our side. All we have to do, is to make sure that we put all the sources inside single shared library. That’s all.

Let’s say we have this special function we want call.

and we have JNI code that is supposed to call it

All we have to do, is to put everything inside one, shared, library.

That’s all. You can find full sample here: recipe № 021.

recipe № 020

Accessing fields of object passed as argument

In this sample I will show you how to access fields of object passed as argument to native method.

We will use three Java classes: PassObject – it will call native methods, CustomClass – class with some fields, OtherClass – class that has some fields and is part of CustomClass.

Structure of the project is quite simple

We need two JavaBean classes (I will not put getters and setters here so I don’t bloat the code with lots of LOCs. All the fields are public, but you can do better here.

We will also need class that calls native method

As you can see, we are passing cc as method parameter. I need to access all the components later inside C code. Most of the work will be done there. The most interesting calls are related to retrieving ids of the fields and getting values from them

You can see “I” passed as last parameter to GetFieldID method. That’s type description. For all primitive types you can use one of the values from the table below

once you have field’s id, simply use one of Get{TYPE}Field methods to retrieve the value of the field.

As for the OtherClass, it’s very similar. The only difference is that you have get the class first.

Note the “LrecipeNo020/OtherClass;” that is class description in JNI. For details, take a look here: docs.oracle.

If you want to run this sample, simply execute following commands

recipe № 019

Throwing exception from C code

Sometimes you need to make sure that error is properly reported inside JVM. If you face some real issues inside native code (especially ones that you can not recover from) it’s good to provide some information back to JVM. Sometimes, the best approach is to throw exception. You can easily do that using ThrowNew function.

recipeno019

In this sample, main part of JNI code is responsible for creating and throwing exception back to Java.

All we have to do is simply throwing object of given class together with message we want to send back to Java code. In fact, that’s all we need to do here.

If you want to run this code, simply clone the repo and run the sample.

recipe № 018

dynamic loading of library in JNI

Sometimes, you want to change native code while JVM is running. In Java, it is not easy to reload native library. However, you can always make a trick by loading it in a wrapper library. In this scenario, what you do is loading native library each time you want to call native code.

recipeno018

There is one step that is important here. You have to make sure to load and call the code from shared library that you want to use

What are the possible cases where you can use this approach?

– you want to change native code while Java application is running
– you want to switch between native implementations that are called from Java (debug/release)
– you want to simulate reloading shared library in Java (note that reloading JNI code in Java is quite cumbersome)

recipe № 017

handling exit calls from external library called via JNI (-Dexit)

Sometimes you have an access to surce code of the library that you want to use. In that case, you can take slightly different approach when it comes to exit call (man 3 exit).
Instead of installing atexit handler that is application wide, you can provide a specific handler for the library. All you have to do is to use “-Dexit=new_handler_name” option. This option will make all calls to exit to be replaced with calls to new_handler_name.
In this sample, I will show how to utilize this approach.
After you are finished with the tutorial, your tree structure for the project should look like this:

In this project we have few files that compose the project. First of all, we have two Java classes that call JNI code. First one, SigTerm.java, call JNI code that, in turn, call library compiled with “-Dexit” switch. Second, SigTermExtLib.java, calls the JNI code, that makes a call to some externaly provided function that we have no influence on (we don’t have sources).
Of course, in this case we have sources for both libs, but we will pretend that we haven’t compiled second library.
So, let’s take a look at the sources.
SigTerm class has just a one purpose – it calls callExitCode(). Inside this function, there is a call to exit (eventually). To see how the implementation was done, take a look at extLibCompiled.c and Makefile.

SigTermExtLib class, has slightly different purpose. It call JNI code that will break JVM. This is the result of the call to exit function that was compiled inside shared library we have no access to. We can’t compile this library, this is why it uses exit from the system implementation. In case of handling this kind of codes, take a look at recipeNo016.

In addition to Java classes we need few more things. First of all, we need the implementation of stopExit function that is used as a new handler for the exit function.

Note that we jump, somewhere, in the function stopExit. The point here is, that we have to make sure that each code that can potentially call exit function must use sigsetjmp before calling the code from the library. Otherwise, we will jump to some random place.

Next piece of the puzzles is the call to exit itself. So, we have two code. First one, calls the exit but is compiled without “-Dexit” switch

Second one, does the same thing. The only difference is that it will be compiled with “-Dexit” switch. Can you see that the code is the same code as previous one? At least in terms of the execution.

The last piece of the solution is the JNI code itself. Here, we have two calls. Both are wrapped with sigsetjmp call and both call very similar functions. The difference here is that first call will prevent exit from killing whole JVM, while second call, will actually close the whole JVM.

When we compile and execute the code, you can see the different behavior of JVM.

Now, take a look at execution itself.

As you can see, it is possible to prevent JNI library, contating call to exit, from killing the whole JVM.

recipe № 016

handling exit calls from external library called via JNI (atexit)

In this sample I will show how to avoid killing your JVM by the external library that makes a call to exit function. We will use atexit function to set a handler for exit calls, and then we will jump out of it using long jump.

After you complete this tutorial, you should end up with the layout similar to this one:

In this tutorial we are using two Java classes that call methods from a single library – libSigTerm. SigTerm.java calls riskyCode() and wraps it with atexit based handler (check man atexit). SigTermNoHandler.java, on the other hand, makes the call to riskyCode() but doesn’t install atexit based handler.

First, let’s take a look at SigTerm.java code. You can find it below. Pay attention to atexit call (we are setting stopExit() to be the code that will be called whenever someone calls exit() – make sure to check man exit -S 3. Call to riskyCode() is wrapped by callExitCode().

Second code, makes the same thing, but it calls different wrapper in JNI. This time, we call callExitCodeNoHandler(). In this case, native code will call riskyCode() without any precautions. You have to take a look at the JNI code to get the feeling what’s the difference.

When it comes to JNI code generated by javac it’s plain simple.

As you can see – no surprises here. We just declare two, external functions: Java_recipeNo016_SigTermNoHandler_callExitCodeNoHandler and Java_recipeNo016_SigTerm_callExitCode.

Implementation is much more interesting. Take a look at different implementation of the call to riskyCode(). Compare Java_recipeNo016_SigTerm_callExitCode and Java_recipeNo016_SigTermNoHandler_callExitCodeNoHandler.

Can you see declaration of riskyCode()? This is the function from our nasty library that we use in our Java code. This function is defined inside externalLib.c, and later on, compiled into shared library.

When everything is in place, we can build all the stuff and perform the test

When we start the test, we can see that we get two different outcomes of the execution

As you can see, first call (wrapped with atexit) thrown an exception that was handled in JVM. Second call, without atexit function, made whole JVM to exit.

recipe № 015

handling SIGSEGV/SIGBUS in JNI code (stop JVM from crashing)

In this sample, I will show you how to prevent JVM from crashing whenever SIGSEGV (Linux) or SIGBUS (OS X) occurs.
This sample will require some low level coding, but I hope you will be able to follow it.
After you complete this tutorial, you should end up with the layout similar to this one:

In this sample, we have two Java classes that call the same native function – riskyCode(). SigSegv handles the SIGSEGV/SIGBUS and SigSegvNoHandler doesn’t care about that.

First code – SigSegv.java – is the code where we call callRiskyCode function (native code). This function makes few things (make sure to check C source). First of all, it sets signal handler, second, it calls the code – riskyCode – third, it either throws exception (in case of error) or sets default handlers (in case of successful execution). Remember, SigSegv.java simply calls native code that does all the tricky things.

As for the SigSegvNoHandler.java we do similar thing. But in this case, we just call callRiskyCodeNoHandler (native code) that calls the buggy code but it doesn’t care about handlers. This is the place where JVM will crash with famous hs_er file.

After we create header files with JNI signatures, we will get following files. Each of them defines one function.

and

These files declare methods that will be called from Java.

The mechanism is very simple. The C code will call riskyCode function two different ways. First time, it will wrap the call with signal handlers. Second time, it will call it as is – no signal handling or whatsoever. If you are completely unfamiliar with signal handlers, make sure to check the info checking man pages – man signal. In our case, we will be interested in two signals (underlined).

(for the full list of signals take a look at Appendix A)

The point here is that for catching illegal access to memory OS X uses SIGBUS while Linux uses SIGSEGV. So, we handle both signals in the code. As for the implementation, we can put everything inside a single file.

After we compile everything

We get he library and compiled Java code. Now, we can run it

As you can see, first call caught the SIGSEGV/SIGBUS and we can see both, message from signal handler (Hello from handler) and Exception related message from Java code (Call to callRiskyCode() finished with exception). In second case, where no signals are caught, we can see that JVM crashes after signal is raised.

recipe № 014

passing memory allocated in C back to Java

In this sample, we will pass arrays created (allocated) inside C back to Java.

To get the feeling of how to pass arrays from Java to C, take a look at recipe № 012. If you want to take a look at how to pass arrays into C and modify them, take a look here: recipe № 013.

The schema for the call follows:

Later on, you can read the explanation for all the primitive types.

After you finish this sample, you should came up with structure similar to one below:

First of all, we need a Java class that will call native code. In this case, library will contain few native functions. Each function will allocate given number of elements. After elements are allocated, they will be returned back to Java.

As you can see, we are passing size of the array into each function. Every native method will create appropriate array and pass it back to Java.

Again, we have to compile the class and create native’s code header.

After this call, header is created

Note, that each function has the same parameter but different return type. You can find different return types: jdoubleArray, jfloatArray, jlongArray, jintArray, jshortArray, jcharArray, jbyteArray, jbooleanArray.

Now, we can generate implementation of the functions. Pay attention to the code. In each function we do the same thing. Reserve object that will be passed back to Java, allocate memory in C, copy data and free memory region inside C.

Compilation is plain and simple

After all elements are in place, all we have to do is to run the sample

As you can see, Java code shows that some of the arrays were allocated and filled with data inside C.