License

The MIT License (MIT)

Copyright (c) 2015 Michal

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Appendix A

1. System signals (man signal)

recipe № D002

Debugging JNI with IntelliJ and CLion

In this recipe I will show you how to debug JNI code with IntelliJ and CLion application

icon_IntelliJIDEAicon_CLion*

We will do following:

– compile C application
– compile Java application
– create CLion project with JNI code
– create IntelliJ project with Java code
– run project in IntelliJ
– attach to running JVM from CLion
– debug JNI function called from Java

First of all, let’s take a look at recipe directory layout. We will end up with the structure that follows (note that we are using exactly the same source code as for recipe № D001):

What we need to run sample is a simple Java application that will call JNI code. In our case, recipeNoD001.HelloWorld class will work perfectly. The code is super simple. It will call native method displayMessage(int value) 1K times.

We can compile this class with following commands

You can also simply type in the terminal

After class is ready, and we have header file with function signature, we can create C code and CMakeList.txt file.

In CMakeList.txt we want to make sure that:

– we use includes from JAVA (they are needed to compile code)
– we are creating shared library inside project tree
– we are creating shared library instead of executable

Now, you can either create CLion project from the File -> New Project … or you can simply open project that is attached to recipe by choosing File -> Open and navigating to recipeNoD001/c.

open

After you open/create project you should be able to see following structure of project

project

Whole project consists of three files: CMakeList.txt, recipeNoD001_HelloWorld.c, and recipeNoD001_HelloWorld.h

clion_c

Before we proceed with debugging, make sure to compile everything and to build shared library. You can easily do it with:

In order to debug JNI code in CLion we have to make sure to attach to running JVM process. This time, we will run the project from IntelliJ. First of all, we have to setup the project. That’s fairly easy. Create empty Java project in IntelliJ. Then, add source directory from the sample code inside recipeNoD001/java. Just add it to project’s sources. You should have the structure similar to following one

java_project_structure

And your project window should contain just one Java file: HelloWorld.java.

java_source

Before you proceed with the execution, there is one more thing you have to do. Java code will use shared library (one that contains JNI code). You have to make sure that Run/Debug configuration (Run -> Edit configurations…) point to the location where shared library is. Take a look below (remember, you can use ${HOME} if you want to refer to location relative to your home directory).

java_run_configuration

Everything is ready for debugging. This time, however, I will not describe the steps. Instead, enjoy the movie.

That’s it! Isn’t that simple ?!

recipe № D001

Debugging JNI with CLion

In this recipe I will show you how to debug JNI code with CLion application

CLion*

We will do following:

– compile application
– create CLion project with JNI code
– start Java application that uses JNI
– attach to running JVM from CLion
– debug JNI function called from Java

First of all, let’s take a look at recipe directory layout. We will end up with the structure that follows:

What we need to run sample is a simple Java application that will call JNI code. In our case, recipeNoD001.HelloWorld class will work perfectly. The code is super simple. It will call native method displayMessage(int value) 1K times.

We can compile this class with following commands

You can also simply type in the terminal

After class is ready, and we have header file with function signature, we can create C code and CMakeList.txt file.

In CMakeList.txt we want to make sure that:

– we use includes from JAVA (they are needed to compile code)
– we are creating shared library inside project tree
– we are creating shared library instead of executable

Now, you can either create CLion project from the File -> New Project … or you can simply open project that is attached to recipe by choosing File -> Open and navigating to recipeNoD001/c.

open

After you open/create project you should be able to see following structure of project

project

Whole project consists of three files: CMakeList.txt, recipeNoD001_HelloWorld.c, and recipeNoD001_HelloWorld.h

clion_c

Before we proceed with debugging, make sure to compile everything and to build shared library. You can easily do it with:

In order to debug JNI code in CLion we have to make sure to attach to running JVM process that will call JNI function. It is now possible to use Attach to Local Process option from Run menu. This way, you can easily connect to running JVM process and debug code directly within CLion (click the image to watch animated GIF).

clion

That’s it! Isn’t that simple ?!

recipe № 030

Abstract method and native implementation

It turns out that JNI provides really cool feature – native implementation of abstract method. It allows to provide different native implementations for the same method, each implemented in different native library.

I guess it’s quite useful in case you want to implement: multiple native interfaces, you have different native codes and you want to choose between different implementations during run time, etc.

Basically, schema follows

In fact, it turns out that implementation is super simple

what we can do, is to provide different implementation (native ones) in classes that are subclassing from from AbstractHelloWorld.

That’s it. We can now easily switch between native implementations like this:

You can find full sample here: recipe № 029

Sources:

1. Native implementation of an abstract method
2. No Best Practices

recipe № 029

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

Let’s say you want to run a daemon. And, for some reasons, you want to launch it using Java. For example, you have some sort of code that is supposed to run as a service. What you can do here is to run daemon initialization using JNI and then, proceed in Java. More or less here is the schema.

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

In addition to that, we need Java part that will be responsible for running “forever loop” where service code should be located.

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.

In this sample, we are getting back to Java (in opposition to sample: recipe № 022). In here, service part is fully maintained by Java. Full sample code for recipe recipe № 029 can be found at following location: recipe № 029 – sample code.

References:

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

recipe № 027

Calling class methods from multiple threads

Calling method of a class (in multithread application) is possible, but you have to pay attention to the way you do it. Typically, situation in thread based code will be very similar to what you can see below.

There are few things you have to consider here. First of all, JVM can have only one, active, thread. It means that each thread running in parallel must acquire access to JVM by attaching to it. You can find description here. Especially, make sure to pay attention to following section:

The JNI interface pointer (JNIEnv) is valid only in the current thread. Should another thread need to access the Java VM, it must first call AttachCurrentThread() to attach itself to the VM and obtain a JNI interface pointer. Once attached to the VM, a native thread works just like an ordinary Java thread running inside a native method. The native thread remains attached to the VM until it calls DetachCurrentThread() to detach itself.

In general, what we want to do, is to create JVM and pass it to all threads. Inside thread’s function, each thread can access JVM by acquiring access to it:

Of course, we need to create JVM instance before we access it. We can do it following way:

And we need to spawn threads as well:

You can download full example, illustrating execution of JVM based code inside C, here: recipeNo027.

References:

  1. J.S. Gray, Komunikacja między procesami w Unixie, ARKANA 1997
  2. Java Native Interface Specification: The Invocation API – link
  3. B. Nichols, PThreads Programming – link

recipe № 024

Calling JNI methods from Threads and how to debug them using gdb

In this sample, I want to take a closer look at Threads and how to attach gdb to running JVM to debug the code.

Situation looks like this. We have a Java code that runs multiple Threads, and each Thread is calling some JNI code. To simplify things, I have one JNI method that calls different native functions depending on parameter’s value.

recipeno024

As you can see, in order to debug the code, we need to attach to running JVM process. Then, we can set breakpoints at locations inside native code.

You can download and run full sample code following way

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