Step Into JAVA Native Programming
What is Java Native or Java Native Interface (JNI)?
JNI is a mechanism or a feature that facilitates to call of functions in a different language like C or C++ program.
NOTE: JNI currently facilitates for C or C++ function invocation.
Reasons for using JNI!
- Access to handle system native features which is not possible to achieve via JavaAPI.
- Access to legacy codes of a particular system for example: Accessing and using WIN32 API or Overriding Windows Callback functions.
- For processing algorithms that need high performance, this is not an issue with later versions of the JVM editions.
Is it possible to use languages other than C and C++?
JNI doesn’t provide functionality other than C and C++, yet there might be third-party APIs that facilitate other languages like Delphi.
Alternative Solution:
Many languages that implement native access mostly choose to use C or C++ therefore functions for other languages can be developed by C and C++ and facilitate to access features via C or C++ is possible.
Compatibility and portability issues when using JNI
As the word says “Native” you must realize that code developed for the system is unique to the system itself therefore you need to create the same functions for other Platform with the related API, for example:
The native function created for Windows OS doesn’t work on Mac OS therefore you need to create a different version for Mac OS this means Java Application is OS Dependent.
Steps in Brief for Using JNI
Step 1:
Create a class and declare methods with the “native” keyword
Important: native method signature is like abstract methods; therefore declare methods without a body as in the preceding example:
public native void myNative();Step 2:
Compile the java class containing the native methods, then generate C header file using “javah” tool located in “X:\Program Files\Java\jdkxxx\bin\”
This will generate a header file containing function prototypes in C styles that you will override them to implement native code.
Run cmd
Type set path = X:\Program Files\Java\jdkxxx\bin\” then enter
javah <ClassName>Know you will get C style header file like this “<ClassName>.h, this will later used to create a DLL that your java application can load with System.loadLibrary(“MyDLL”);
IMPORTANT: the javah generated a header file containing prototype functions in static form therefore DLL type must be a static DLL which will be explained later.
Step 3:
Create a C or C++ DLL:
For creating a DLL you can use Visual C++, Qt, RAD Studio.
Example: Simple Program with JNI integration.
In this example I will demonstrate how to integrate JNI with a Java application, creating a Static DLL with Visual C++, I’m going to use Visual C++ 2013 version yet there is no issue with using later versions like 2008, 2010 same as with 2013 version, Eclipse will be used to create the Java Application.
This example is intended to demonstrate the most basic functionality by performing a simple calculation with C++ and output in Java data representation then delegating the value (return by C++ function) to the Java native method so the JVM can retrieve the value implicitly.
Create Java Project:
I’m currently using Eclipse IDE to demonstrate this example.
Step 1:
File — New — “JAVA Project” dialog will open as below then name your project and click “finish”.
Step 2:
After creating a project create a package (right click on src choose package or file — new — package) “com.srg.mynatives” as preceding or with any name,
The reason to use packages is that it’s somewhat different when native method prototype declarations when the java classes containing native methods were within a package, so I’m going to demonstrate that too.
After that create another package “com.srg.test”.
Step 3:
Create a java class “MyNatives.java” for native method declaration in “com.srg.mynatives”.
The source code should be as the one specified here:
package com.srg.mynatives;public class MyNative {
//Declare native methods.
public native double getTotal(double val1, double val2);
}Step 4:
Create a Visual C++ DLL project, for this scenario, I’m using Visual C++ 2013 version.
File –> New –> Project
This DLL uses the Microsoft Foundation Class (MFC) library therefore when distributing a Java application with an MFC DLL you may need to install Visual C++ Redistributable appropriate version, in my case I need to install Visual Redistributable 2013 x64 or x86 depending on the DLL processor architecture.
Specify a name for your project and save it to a location then click “OK”
Then “MFC DLL Wizard” will open click “Next”
Select DLL type “Regular DLL with MFC statically linked” literally that is a “Static DLL” with MFC support.
The benefit of choosing this option is dependencies used are included in the DLL therefore DLL is large in size and you may not need to distribute some dependencies (or DLLs) separately.
Click “Finish”,
After that project will start creating and may take some time to parse classes and generate the project.
Step 5:
Generate “C” style header file for “MyNative.java” using “javah.exe” tool
For this to perform first you must compile the “MyNative.java” and then specify the “MyNative” class name to “javah.exe” tool to generate the header file.
Run in command line type: set path=D:\Program Files\Java\jdk1.7.0_45\binKnow set the folder environment where the compiled classes exist in the Eclipse project
In my case, it’s in “G:\Java Research Lab\Projects\JNIBasics\bin”
Get Roshan Gerard’s stories in your inbox
Join Medium for free to get updates from this writer.
Set path as preceding “cd G:\Java Research Lab\Projects\JNIBasics\bin” enter then change the driver to “G:”
After that generate the header file as described, as I said earlier regarding the packages there is the part that demonstrates how to generate a header file for a class in the package.
“javah com.srg.mynatives.MyNative “ enter then the header will generate with the name “com_srg_mynatives_MyNative.h” You can change the name if you like.
As you can see the class name is specified in the package declaration.
I’m changing the name of the generated header file to “MyHeader.h”
Step 6:
Adding header file to Visual C++ project
Copy the header file into the Visual C++ project folder’s solution folder’s folder in the project name
My project is as below:
“x:\StepIntoJNI\StepIntoJNI_s\StepIntoJNI\MyHeader.h”
The solutions folder is “StepIntoJNI_s”
After that add the header file to your project from the “Solution Explorer”
From the “Solution Explorer” — Right click on “Header Files” node — Add — Existing Item.
From the “Add Existing Item” dialog select the “MyHeader.h” and click “Add”
Step 7:
Add JNI library locations to Visual C++ project.
From “Solution Explorer” — Right click on <project_name> — select “Properties”.
In the project properties dialog navigate to “VC++ Directories — Include Directories — click on the drop-down arrow and select “<Edit>”
In the “Include Directories” dialog click on “folder” icon then add “JNI” library locations
Currently, there are two locations to define, include libraries were exist in the JDK folder,
There are two locations as below:
“D:\Program Files\Java\jdk1.7.0_45\include”
“D:\Program Files\Java\jdk1.7.0_45\include\win32” then click “OK” and save settings.
Step 8:
Create a “.CPP” file to override the “C” style prototypes in the “MyHeader.h” file
From “Solution Explorer” — Right-click on the “Source Files” node — Add — New Item.
From the “Add New Item” dialog Navigate to “Visual C++” — Select “C++ File (.cpp)”, Specify name for the CPP file I’m just naming it as “MyCPP.cpp” then click on “Add”.
Step 9:
Overriding the prototype functions in the “MyCPP” source file.
Open “MyCPP” from the “Solution Explorer” and then specify the code as below.
#include "stdafx.h" //This should be included.
#include <jni.h> //This should always include on every CPP file that "MyHeader.h" included.
#include "MyHeader.h"JNIEXPORT jdouble JNICALL Java_com_srg_mynatives_MyNative_getTotal(JNIEnv *env, jobject object, jdouble val1, jdouble val2){
return (val1 + val2);
}Finally, save the project.
Step 10:
Build configuration for the DLL,
DLL to work with the current architecture that JVM runs at x86 or x64 the DLL must be the same architecture as the JVM architecture.
From “Main Menu” — “Build” — Click on “Configuration Manager”.
In the “Configuration Manager” dialog choose “<New>….” from the “Active solution platform” combo box.
In the “New Solution Platform” dialog choose a desired platform between “x86 (Win32)” This is default created or x64 I’m choosing x64 because my JRE is x64.
Then click “OK”.
Finally build the DLL: Main Menu — Build — Click on “Build Solution” then DLL will be generated in the path as preceding “x:\StepIntoJNI\StepIntoJNI_s\x64\Debug”.
Step 11:
Copy the generated DLL to Eclipse project location “x: \JNIBasics\”.
Open the eclipse project “JNIBasics” and create a new class called “Test.java” in “com.srg.test” package as in the figure.
Open the “Test.java” and then add the code specified below.
package com.srg.test;import com.srg.mynatives.MyNative;/**
*
* @author Roshan Gerard Bolonna
*
*/
public class Test { /**
* @param args
*/
public static void main(String[] args) {
/*
* Load the DLL at the startup, before invoking any native methods.
*/
System.loadLibrary("StepIntoJNI");
MyNative myn = new MyNative();
double total = myn.getTotal(50, 45.54);
System.out.println("Natively Performed Calculation: "+total); }}
When executed output will be as in the below figure.
The End….!
This is my first post published through LinkedIn, regarding Java Native Programming an introductory tutorial, that contains very simple examples with in-depth guidance for starters.
Hope this will be a good tutorial for programmers who like building their components who would like to do things differently and innovatively and embrace developing system software.
Please feel free to message me via LinkedIn regarding any misconceptions or errors in this post
Thank you…!





