How to compile and execute DLL using JNI in Java on Fedora?

Compile and Execute DLL using JNI in Java on Fedora is a common practice in cross platform programming. Java Native Interface, as the name indicates, is an interface between Java App code and other codes like C/C++ programs. After creating and compiling the Java file containing specific functionality, header files can be created by using JNI. These header files then are included in C/C++ program to run functions coded in Java.

Dynamic Link Library is commonly termed as DLL is a file type used to group instructions that are executed by other programs. A DLL file itself does nothing, it provide functionality to other programs. DLLs are very helpful in making efficient application since they get loaded in memory only when needed by the calling program. One DLL file can be shared by multiple programs thus improving resource utilization.

This is demonstrated with Java code to implement basic arithmetic operations. The cal1.Java is compiled and cal1.h file is created. It is then used in try1.c file.

Steps to compile and execute DLL using JNI in Java on Fedora

  1. Compile the java program written for DLL by using the following command on the terminal:

javac cal1.java

  1. Create the header file for the java program by using the following command:

javah -jni cal1

  1. Compile the C program written as a part of DLL execution by taking the reference from the Java header file.

Type the following command in the terminal. Follow the substeps to find out the paths of the JNI files.

gcc -I /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.79-2.5.5.0.fc20.x86_64/include/ -I/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.79-2.5.5.0.fc20.x86_64/include/linux/ -shared -o libcalc.so try1.c

  1. locate the jni.h file and copy its path at the place of path1 in the note below
  2. locate the jni_md.h file and copy its path at the place of  path2 in the note below
  3. Note for C file Execution: gcc path1 path2 -shared -o lib***. So nameOFC.c is the short term for the 3rd step.
  4. Run the java file to get the results on the terminal:
    java –Djava.library.path=`pwd` cal1

Note that here, pwd the path where the DLL file is located. cal1 is the name of the main class in the java file.

This way we are able to execute DLL program for a calculator in Fedora.

cal1.java
 
import java.util.*;
public class cal1
{
 static
  {
     System.loadLibrary("calc");
  } 
  
private native double addFunc(double a,double b);
private native double subFunc(double a,double b);
private native double mulFunc(double a,double b);
private native double divFunc(double a,double b);
 public static void main(String arg[]) throws Exception
{
  //cal c=new cal();
Scanner sc=new Scanner(System.in);
  
  int choice=1;
  double num1,num2;
        
        while(choice!=5)
      {  
                  System.out.println("\n Enter choice \n1.Add\n2.Subtract\n3.Multiply\n4.Division\n5.exit"); 
                  choice=sc.nextInt();      
                  
                  
                  System.out.println("\n Number 1 : "); 
                  num1=sc.nextDouble();      
                  
                  System.out.println("\n Number 2 :"); 
                  num2=sc.nextDouble();      
                  
                  switch(choice)
                  {      
                  
                        case 1:              
                               System.out.println("Sum of Two Numbers is ="+new cal1().addFunc(num1,num2)); 
                              break;
                        case 2:
                              System.out.println("Difference of Two Numbers is="+new cal1().subFunc(num1,num2));
                              break;                  
                        case 3:
                              System.out.println("Product of Two Numbers="+new cal1().mulFunc(num1,num2));
                              break;                  
                        case 4:
                              System.out.println("Division of Numbers="+new cal1().divFunc(num1,num2));
                              break;                  
                  }
      }
}
}
cal1.h
 
#include <jni.h>
/* Header for class cal1 */
#ifndef _Included_cal1
#define _Included_cal1
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     cal1
 * Method:    add
 * Signature: (DD)D
 */
JNIEXPORT jdouble JNICALL Java_cal1_addFunc
  (JNIEnv *, jobject, jdouble, jdouble);
/*
 * Class:     cal1
 * Method:    sub
 * Signature: (DD)D
 */
JNIEXPORT jdouble JNICALL Java_cal1_subFunc
  (JNIEnv *, jobject, jdouble, jdouble);
/*
 * Class:     cal1
 * Method:    mul
 * Signature: (DD)D
 */
JNIEXPORT jdouble JNICALL Java_cal1_mulFunc
  (JNIEnv *, jobject, jdouble, jdouble);
/*
 * Class:     cal1
 * Method:    div
 * Signature: (DD)D
 */
JNIEXPORT jdouble JNICALL Java_cal1_divFunc
  (JNIEnv *, jobject, jdouble, jdouble);
#ifdef __cplusplus
}
#endif
#endif
try1.c
 
  1. #include<jni.h>
  2. #include<stdio.h>
  3. #include"cal1.h"
  4. JNIEXPORT jdouble JNICALL Java_cal1_addFunc(JNIEnv *env, jobject obj, jdouble a, jdouble b)
  5. {
  6. return(a+b);
  7. }
  8. JNIEXPORT jdouble JNICALL Java_cal1_subFunc(JNIEnv *env, jobject obj, jdouble a, jdouble b)
  9. {
  10. return(a-b);
  11. }
  12. JNIEXPORT jdouble JNICALL Java_cal1_mulFunc(JNIEnv *env, jobject obj, jdouble a, jdouble b)
  13. {
  14.       return (a*b);
  15. }
  16. JNIEXPORT jdouble JNICALL Java_cal1_divFunc(JNIEnv *env, jobject obj, jdouble a, jdouble b)
  17. {
  18.       return (a/b);
  19. }