Many a times its a requirement that from Java we like to access/call a function which is written in a different language other than Java, let's say "C".
Yes, in Java it is possible to invoke native language function.
Here are the steps which needs to be followed to access the a native function.
1) Create a "Student.java" file to call the method "getRank"
2) Compile "Student.java" file to generate the class file
3) Generate a "Student.h" file
4) Create a "StudentResult.c" file to write a method which returns the student result
5) Download "Tiny C" and set class path
6) Compile "C" file created inside step #4
7) Modify "Student.java" program to load generated dll file
8) Run program to see output
We will see an example of retrieving a rank of a student based on the student id. We will pass student id to a function called "getRank". "getRank" function is written inside a "C" language. So in this example not only we are going to access "C" function but we will also see how can we create a native library i.e. ".dll" file.
Here are the steps in detail:
1) Create a "Student.java" file to call the method "getRank"
Here we have created "Student" class which returns the result from the "getRank" method which is written in "C".
/**
Program which calls a native "c" method. It calls the "getRank" method which is written in "C" and returns value of student rank based on the student rollNumber passed via command line argument.
**/
public class Student {
public native int getRank(int rollNumnumber);
public static void main(String[] args) {
Student ja = new Student();
int rank = ja.getRank(Integer.parseInt(args[0]));
System.out.println("Rank of Student Id " + args[0] + " is " + rank);
}
}
2) Compile "Student.java" file to generate the class file
Now, go to the project structure where your java program "Student.java" is available. and fire below command to generate "Student.class" file.
c:/studentrecords>javac Student.java
Once command is successfully executed you should see two files in your project directory (In our case "C:/studentrecords").
Files are:
i)Student.java
ii)Student.class
3) Generate a "Student.h" file
Once "Student.class" is generated next steps is to create a machine generate "Student.h" file.
Fire below command from the project directory to automatically generate "student.h" file.
c:/studentrecords>javah -jni Student
Once command is successfully executed look at the project directory again i.e. "C:/studentrecords".
Now, you should see below three files:
i) Student.java
ii)Student.class
iii)Student.h (generated in step #3)
FYI, content of the "Student.h" file looks like this
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Student */
#ifndef _Included_Student
#define _Included_Student
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Student
* Method: getRank
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_Student_getRank
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
4) Create a "StudentResult.c" file to write a method which returns the student result
Now, we need to create a "StudentResult.c" file in which "getResult" method resides. A method which we have called from the "Student.java" file.
Here is the sample "StudentResult.c" file.
#include<stdio.h>
#include"jni.h"
#include"Student.h"
JNIEXPORT jint JNICALL Java_Student_getRank (JNIEnv *env, jobject obj, jint rollNumber) {
if(rollNumber == 20) {
return 1;
} else {
return 2;
}
}
In our cases we have used a static logic i.e. if rollNumber which is passed from the java program is 20 then his/her rank is 1 (one) else we will return 2 (two) as a rank for all other rollNumbers.
Note: here method signature we have simply copied from the "Student.h" file. i.e. below line
JNIEXPORT jint JNICALL Java_Student_getRank (JNIEnv *env, jobject obj, jint rollNumber);
We need to save this file in the same project directory. Hence post step #4 we must have below four files in our project directory (C:/studentrecords).
i) Student.java
ii)Student.class
iii)Student.h (generated in step #3)
iv) StudentResult.c (created in step #4)
5) Download "Tiny C" and set class path
We need to compile our "StudentResult.c" file and generate "StudentResult.dll" and "StudentResult.def" file.
To compile "C" file we need a "C" compiler. In our example we will use Tiny C compiler to compile our "Student.c" file.
To download Tiny C, please use link "http://download.savannah.gnu.org/releases/tinycc/".
For our example we have used "tcc-0.9.25-win32-bin.zip" from mentioned link.
Once its downloaded we need to extract the "tcc-0.9.25-win32-bin.zip" to the location "C:/studentrecords/tcc" and set the "C:/studentrecords/tcc" path into the system "path" variable. i.e. path where "tcc.exe" can be found.
6) Compile "C" file created inside step #4
Once "Tiny C" compiler is set to compile our "StudentResult.c" file and path variable is set we need to fire below command.
C:/studentrecords> tcc "StudentResult.c" -I "C:\Program Files (x86)\Java\jdk1.7.0_79\include" -I "C:\Program Files (x86)\Java\jdk1.7.0_79\include\win32" -shared -o StudentResult.dll
Once command is successfully executed it will generate two more files in the location of your project directory (C:/studentrecords).
i.e.
i) StudentResult.def
ii)StudentResult.dll
Hence post step #5 we must have below six files in our project directory (C:/studentrecords).
i) Student.java
ii)Student.class
iii)Student.h (generated in step #3)
iv) StudentResult.c (created in step #4)
v) StudentResult.def (generated in step #6)
vi)StudentResult.dll (generated in step #6)
7) Modify "Student.java" program to load generated dll file
Now, we need to modify the "Student.java" file which we created in step #1 to load newly created "StudentResult.dll" file.
We can use "System.loadLibrary("StudentResult");" to load the library file which we generated in step #6.
For your quick reference this is how our java program looks like after loading "StudentResult" file.
/**
Program which calls a native "c" method. It calls the "getRank" method which is written in "C" and returns value of student rank based on the student rollNumber passed via command line argument.
**/
public class Student {
public native int getRank(int rollNumnumber);
public static void main(String[] args) {
Student ja = new Student();
int rank = ja.getRank(Integer.parseInt(args[0]));
System.out.println("Rank of Student Id " + args[0] + " is " + rank);
}
static {
//Load "StudentResult" library in which "getRank" method is available.
System.loadLibrary("StudentResult");
}
}
FYI, we have loaded "StudentResult file in a static block so that as and when our class is loaded in memory at the same time static block gets executed and StudentResult library is loaded.
8) Run program to see output
We need to compile our "Student.java" program one more time as we modify that file in Step #7.
So we need to fire below command to re-generate Student.class file.
c:/studentrecords>javac Student.java
Now, we have latest "Student.class" file available. To verify output we need to execute "Student" program from command line like this.
1st run "Student" program with student id "20"
C:/studentrecords> java Student 20
Rank of Student Id 20 is 1
2nd run "Student" program with student id other than "20" lets say "50"
C:/studentrecords> java Student 50
Rank of Student Id 50 is 2
We are done!
Cheers!
Henal Saraiya
Yes, in Java it is possible to invoke native language function.
Here are the steps which needs to be followed to access the a native function.
1) Create a "Student.java" file to call the method "getRank"
2) Compile "Student.java" file to generate the class file
3) Generate a "Student.h" file
4) Create a "StudentResult.c" file to write a method which returns the student result
5) Download "Tiny C" and set class path
6) Compile "C" file created inside step #4
7) Modify "Student.java" program to load generated dll file
8) Run program to see output
We will see an example of retrieving a rank of a student based on the student id. We will pass student id to a function called "getRank". "getRank" function is written inside a "C" language. So in this example not only we are going to access "C" function but we will also see how can we create a native library i.e. ".dll" file.
Here are the steps in detail:
1) Create a "Student.java" file to call the method "getRank"
Here we have created "Student" class which returns the result from the "getRank" method which is written in "C".
/**
Program which calls a native "c" method. It calls the "getRank" method which is written in "C" and returns value of student rank based on the student rollNumber passed via command line argument.
**/
public class Student {
public native int getRank(int rollNumnumber);
public static void main(String[] args) {
Student ja = new Student();
int rank = ja.getRank(Integer.parseInt(args[0]));
System.out.println("Rank of Student Id " + args[0] + " is " + rank);
}
}
2) Compile "Student.java" file to generate the class file
Now, go to the project structure where your java program "Student.java" is available. and fire below command to generate "Student.class" file.
c:/studentrecords>javac Student.java
Once command is successfully executed you should see two files in your project directory (In our case "C:/studentrecords").
Files are:
i)Student.java
ii)Student.class
3) Generate a "Student.h" file
Once "Student.class" is generated next steps is to create a machine generate "Student.h" file.
Fire below command from the project directory to automatically generate "student.h" file.
c:/studentrecords>javah -jni Student
Once command is successfully executed look at the project directory again i.e. "C:/studentrecords".
Now, you should see below three files:
i) Student.java
ii)Student.class
iii)Student.h (generated in step #3)
FYI, content of the "Student.h" file looks like this
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Student */
#ifndef _Included_Student
#define _Included_Student
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Student
* Method: getRank
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_Student_getRank
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
4) Create a "StudentResult.c" file to write a method which returns the student result
Now, we need to create a "StudentResult.c" file in which "getResult" method resides. A method which we have called from the "Student.java" file.
Here is the sample "StudentResult.c" file.
#include<stdio.h>
#include"jni.h"
#include"Student.h"
JNIEXPORT jint JNICALL Java_Student_getRank (JNIEnv *env, jobject obj, jint rollNumber) {
if(rollNumber == 20) {
return 1;
} else {
return 2;
}
}
In our cases we have used a static logic i.e. if rollNumber which is passed from the java program is 20 then his/her rank is 1 (one) else we will return 2 (two) as a rank for all other rollNumbers.
Note: here method signature we have simply copied from the "Student.h" file. i.e. below line
JNIEXPORT jint JNICALL Java_Student_getRank (JNIEnv *env, jobject obj, jint rollNumber);
We need to save this file in the same project directory. Hence post step #4 we must have below four files in our project directory (C:/studentrecords).
i) Student.java
ii)Student.class
iii)Student.h (generated in step #3)
iv) StudentResult.c (created in step #4)
5) Download "Tiny C" and set class path
We need to compile our "StudentResult.c" file and generate "StudentResult.dll" and "StudentResult.def" file.
To compile "C" file we need a "C" compiler. In our example we will use Tiny C compiler to compile our "Student.c" file.
To download Tiny C, please use link "http://download.savannah.gnu.org/releases/tinycc/".
For our example we have used "tcc-0.9.25-win32-bin.zip" from mentioned link.
Once its downloaded we need to extract the "tcc-0.9.25-win32-bin.zip" to the location "C:/studentrecords/tcc" and set the "C:/studentrecords/tcc" path into the system "path" variable. i.e. path where "tcc.exe" can be found.
6) Compile "C" file created inside step #4
Once "Tiny C" compiler is set to compile our "StudentResult.c" file and path variable is set we need to fire below command.
C:/studentrecords> tcc "StudentResult.c" -I "C:\Program Files (x86)\Java\jdk1.7.0_79\include" -I "C:\Program Files (x86)\Java\jdk1.7.0_79\include\win32" -shared -o StudentResult.dll
Once command is successfully executed it will generate two more files in the location of your project directory (C:/studentrecords).
i.e.
i) StudentResult.def
ii)StudentResult.dll
Hence post step #5 we must have below six files in our project directory (C:/studentrecords).
i) Student.java
ii)Student.class
iii)Student.h (generated in step #3)
iv) StudentResult.c (created in step #4)
v) StudentResult.def (generated in step #6)
vi)StudentResult.dll (generated in step #6)
7) Modify "Student.java" program to load generated dll file
Now, we need to modify the "Student.java" file which we created in step #1 to load newly created "StudentResult.dll" file.
We can use "System.loadLibrary("StudentResult");" to load the library file which we generated in step #6.
For your quick reference this is how our java program looks like after loading "StudentResult" file.
/**
Program which calls a native "c" method. It calls the "getRank" method which is written in "C" and returns value of student rank based on the student rollNumber passed via command line argument.
**/
public class Student {
public native int getRank(int rollNumnumber);
public static void main(String[] args) {
Student ja = new Student();
int rank = ja.getRank(Integer.parseInt(args[0]));
System.out.println("Rank of Student Id " + args[0] + " is " + rank);
}
static {
//Load "StudentResult" library in which "getRank" method is available.
System.loadLibrary("StudentResult");
}
}
FYI, we have loaded "StudentResult file in a static block so that as and when our class is loaded in memory at the same time static block gets executed and StudentResult library is loaded.
8) Run program to see output
We need to compile our "Student.java" program one more time as we modify that file in Step #7.
So we need to fire below command to re-generate Student.class file.
c:/studentrecords>javac Student.java
Now, we have latest "Student.class" file available. To verify output we need to execute "Student" program from command line like this.
1st run "Student" program with student id "20"
C:/studentrecords> java Student 20
Rank of Student Id 20 is 1
2nd run "Student" program with student id other than "20" lets say "50"
C:/studentrecords> java Student 50
Rank of Student Id 50 is 2
We are done!
Cheers!
Henal Saraiya