(Note: This post is principally relevant for MS Windows users.)
Vertoda doesn't use JNI directly but we have used it for other projects. In a nutshell, JNI (Java Native Interface) is a Java programming library that runs in the Java VM (Virtual Machine) and can call or be called by programs written for specific hardware or operating systems (referred to as native applications) as well as programs deployed as libraries and written in languages such as C and C++.
JNI is a very useful tool for accessing legacy code or libraries specific to a particular operating system. Device driver software is a good example as drivers for printers, monitors etc. are typically written for a specific operating system. Another example would be software for Serial COM ports. Data coming into acquisition boards for WSNs can be detected by a Java program listening on the Serial COM port to which the board is attached using the Java Communications API (http://java.sun.com/products/javacomm/). Given that Serial Port access is OS specific, this API uses JNI to access programs performing MS Windows specific functionality. A separate LINUX version is also available (http://www.agaveblue.org/howtos/Comm_How-To.shtml).
However, JNI can be frustrating to use initially. One must ensure that the paths to any libraries accessed are included. For example, let's say we're using a library called MyTest.dll and it's located in a directory called C:\MyDLLs. (A dynamic link library or DLL is a Microsoft Windows specific library.) Assume that we also have a Java JAR using JNI to access this DLL called MyJNITest.jar. We run the program using the following command:
java -Djava.library.path="C:\MyDLLs" -jar MyJNITest.jar
Note that we reference the path to the DLL in our -D runtime option but not the DLL file itself. If you don't specify this path you will get the following error:
java.lang.UnsatisfiedLinkError: no MyTest.dll in shared library path
Unfortunately, if our DLL depends on another DLL (say, MyOtherDLL.dll) then we will still get the following error:
java.lang.UnsatisfiedLinkError: "Can't Find Dependent Libraries"
This appears to be because JNI looks in the directory we specify for our java.library.path option but looks in the PATH environment variable for the directory location of DLLs on which our own DLL depends.
The first thing to do is find out what other DLLs our own DLL depends on. The easiest way to achieve this if you have Microsoft Visual Studio installed is the following:
- Open a Command Line Window.
- You will be using a file called dumpbin.exe. If you have Visual Studio installed this will be in C:\Program Files\Microsoft Visual Studio 8\VC\bin so cd to this directory.
- Assuming our DLL is called MyTest.dll and is located in the C:\MyDLLs directory path we would run the following command:
dumpbin.exe "C:\MyDLLs\MyTest.dll" /dependents
- (Note that dumpbin.exe can be problematic on MS Vista. This will be the subject of another post.)
- This will show what other libraries and DLLs our file depends on.
Let's assume we have one dependency called MyOtherDLL.dll located in a directory called C:\MyOtherDLLs. We can now add this directory to our path variable as follows:
- On MS Vista click on the Windows button | Computer | System Properties to open the Control Panel.
- Click on Advanced System Settings to open the System properties dialog and click on the Environment Variables pushbutton.
- This opens the Environment Variables dialog window.
- In the System Variables listbox select the PATH environment variable and click on the Edit pushbutton.
- Assuming your dependency is located in C:\MyOtherDLLs add this to the path variable. Ensure that you postfix a semi-colon (;). Prefix a semi-colon (;) if it's the last entry.
You should now be able to run your JNI program.