// Assumption: I assume that you have already installed Java SDK, gfortran, g++ on your machine and you are using Linux.
-
Open a Terminal
-
Create a directory named
src/com/sangeethlabs/jni/
to create the source files andbin
to keep the compiled code and shared objects.mkdir -p src/com/sangeethlabs/jni mkdir bin
-
Open your favourite text editor, create a new file and write the following code
package com.sangeethlabs.jni; public class Fortran { static { System.loadLibrary("FortranJNI"); } public synchronized native static int sum(int a, int b); public static void main(String[] args) { int a = 10, b = 30; int result = Fortran.sum(a, b); System.out.printf("%s + %s = %s\n", a, b, result); } }
Save the file as
Fortran.java
undersrc/com/sangeethlabs/jni/
directory.
// NOTE: Ensure that the class name and the file name are same. -
Create a new file and write the following Fortran code
INTEGER FUNCTION FORTRANSUM(I,J) FORTRANSUM = I+J RETURN END
Save the file as
fortran.f
undersrc/
directory. -
Go back to your Terminal
-
Run the following command to compile the Java source code:
javac -d bin src/com/sangeethlabs/jni/Fortran.java
This generates a class file named
Fortran.class
under the directorybin/com/sangeethlabs/jni/
. -
Run the following command to compile the Fortran source code:
gfortran -c -o "bin/fortran.o" src/fortran.f
This generates the object file
fortran.o
underbin/
directory. -
Now run the following command to generate header file for the Java Native Interface code.
javah -d src -classpath bin com.sangeethlabs.jni.Fortran
This results in a C/C++ header file named
com_sangeethlabs_jni_Fortran.h
under the directorysrc/
with the following contents/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_sangeethlabs_jni_Fortran */ #ifndef _Included_com_sangeethlabs_jni_Fortran #define _Included_com_sangeethlabs_jni_Fortran #ifdef __cplusplus extern "C" { #endif /* * Class: com_sangeethlabs_jni_Fortran * Method: sum * Signature: (II)I */ JNIEXPORT jint JNICALL Java_com_sangeethlabs_jni_Fortran_sum (JNIEnv *, jclass, jint, jint); #ifdef __cplusplus } #endif #endif
-
Open your favourite text editor, create a new file and write the following C++ code
#include "com_sangeethlabs_jni_Fortran.h" #include <jni.h> extern"C" { int fortransum_(int *, int *); } /* * Class: com_sangeethlabs_jni_Fortran * Method: sum * Signature: (II)I */ JNIEXPORT jint JNICALL Java_com_sangeethlabs_jni_Fortran_sum(JNIEnv *env, jclass kclass, jint a, jint b) { return fortransum_(&a,&b); }
Save the file as
com_sangeethlabs_jni_Fortran.cpp
undersrc/
directory. -
Run the following command to compile the C++ source code
g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -fPIC -c -o "bin/com_sangeethlabs_jni_Fortran.o" src/com_sangeethlabs_jni_Fortran.cpp
This generates an object file
com_sangeethlabs_jni_Fortran.o
under the directorybin/
.The compiler option
-fPIC
is required to create a shared library with the object filecom_sangeethlabs_jni_Fortran.o
. -
Now create a shared library named
libFortranJNI.so
withcom_sangeethlabs_jni_Fortran.o
andfortran.o
under the directorybin/
using the following commandg++ -shared -o "bin/libFortranJNI.so" bin/fortran.o bin/com_sangeethlabs_jni_Fortran.o
-
Now run the following command to execute the Java class.
java -cp bin -Djava.library.path=bin com.sangeethlabs.jni.Fortran
The output of the program will be as shown below,
10 + 30 = 40
// NOTE: “-Djava.library.path=.” option indicates to JVM that “libFortranJNI.so” can be located under the current directory. Another alternative is to set the environment variable LD_LIBRARY_PATH to include the path under which “libFortranJNI.so” can be located. By doing so, we can execute the Java code as shown below
export LD_LIBRARY_PATH=bin:$LD_LIBRARY_PATH java -cp bin com.sangeethlabs.jni.Fortran
Now you have successfully invoked a Fortran function from a Java program using Java Native Interface !