Java Introduction to JNI Prepared by Humaira Siddiqui.

20
Java Introduction to JNI Prepared by Humaira Siddiqui

Transcript of Java Introduction to JNI Prepared by Humaira Siddiqui.

Page 1: Java Introduction to JNI Prepared by Humaira Siddiqui.

Java Introduction to JNI

Prepared by Humaira Siddiqui

Page 2: Java Introduction to JNI Prepared by Humaira Siddiqui.

What is JNI? -1

JNI stands for Java Native Interface JNI specifies a communication protocol between Java code

and external, native code. It enables your Java code to interface with native code

written in other languages (such as C, C++) Java native methods are methods declared in your Java

code (much like you declare an abstract method), but which are actually implemented in another programming language

Page 3: Java Introduction to JNI Prepared by Humaira Siddiqui.

What is JNI? -2

JNI allows Java programmers to Leverage the improved speed possible with natively

compiled code (such as C or assembler). For example, you might need an extremely fast math routine for a scientific application or game program.

Utilize existing code libraries of native code in your Java programs. For example, there might be a really good file compression library written in C. Why try to rewrite it in Java when you can access it (as is) using JNI?

Page 4: Java Introduction to JNI Prepared by Humaira Siddiqui.

What is JNI? -3

JNI Drawbacks Your program is no longer platform independent Your program is not as robust. If there is a null pointer

exception in your native code, the JVM can't display a helpful message. It might even lock up.

Page 5: Java Introduction to JNI Prepared by Humaira Siddiqui.

What is JNI? -4

JNI supports Native methods can create and manipulate Java objects

such as strings and arrays. Native methods can manipulate and update Java objects

passed into them (as parameters) You can catch and throw exceptions from native

methods and handle these exceptions in either the native method or your Java application

This almost seamless sharing of objects makes it very easy to incorporate native methods in your Java code

Page 6: Java Introduction to JNI Prepared by Humaira Siddiqui.

Writing JNI Methods -1

You write JNI programs for C/C++ by doing the following

1. Create a Java class that declares the native method, contains code for loading the native library. The class should also contain a main method which calls the native method

2. Compile the Java class

3. Run the javah tool with the -jni option to generate a header file for your native C/C++ code

4. Write the C/C++ code (file) which implements the method defined in the header file

5. Compile the header and C/C++ code into a library (a DLL under Windows)

6. Run the Java class (main method)

Page 7: Java Introduction to JNI Prepared by Humaira Siddiqui.

Writing JNI Methods -2

1. Write Your Java class

package com.cexp.wms.jni.examples;class HelloWorld { public native void displayHello(); //native method { System.loadLibrary("c_library"); }

public static void main(String[] args) { HelloWorld hw = new HelloWorld();

hw.displayHello(); } }

Page 8: Java Introduction to JNI Prepared by Humaira Siddiqui.

Writing JNI Methods -3

2. Compile your class

javac HelloWorld.java

Page 9: Java Introduction to JNI Prepared by Humaira Siddiqui.

Writing JNI Methods -4

3. Create the header (.h) file by using the javah tool

javah -jni -o HelloWorld.h -classpath . com.cexp.jni.examples.HelloWorld

(Note: entire command must be on one line)

This command will create a file called HelloWorld.h

which contains a C function signature for implementing

the native method.

The C header file will include <jni.h>, the standard header file

for JNI applications.

Page 10: Java Introduction to JNI Prepared by Humaira Siddiqui.

Writing JNI Methods -53. The header file it creates will look something like

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class HelloWorld */

#ifndef _Included_HelloWorld

#define _Included_HelloWorld

#ifdef __cplusplus extern "C" {

#endif

JNIEXPORT void JNICALL

Java_com_cexp_wms_jni_examples_HelloWorld_displayHello

(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

Page 11: Java Introduction to JNI Prepared by Humaira Siddiqui.

Writing JNI Methods -6

The displayHello routine has two parameters (standard for all JNI native methods). JNI Env * -- JNI interface pointer. We can use this

pointer to make useful calls like GetStringUTFChars(), which allows us to convert Java Unicode (2 byte) strings to UTF-8 (1 byte) strings.

jobject -- A reference to the (calling) object itself. Similar to this

Page 12: Java Introduction to JNI Prepared by Humaira Siddiqui.

Writing JNI Methods -7 JNI native methods can access the following types

boolean jboolean

string jstring

byte jbyte

char jchar

short jshort

int jint

long jlong

float jfloat

double jdouble

void void

Page 13: Java Introduction to JNI Prepared by Humaira Siddiqui.

Writing JNI Methods -8

All of these types can be accessed directly except for jstring, which requires a subroutine call to in order to convert a Java Unicode string (2 bytes) to a C-style char* string (1 byte UTF-8 format).

Page 14: Java Introduction to JNI Prepared by Humaira Siddiqui.

Writing JNI Methods -94. Write the native C/C++ code which implements the method.

Use the same signature that your header file uses. You might name your file something like "HelloWorld.c".

#include <jni.h>

#include "HelloWorld.h"

#include <stdio.h>

JNIEXPORT void JNICALL

Java_com_cexp_wms_jni_examples_HelloWorld_displayHello (JNIEnv *env, jobject obj)

{

printf("Hello world! I'm here! \n");

return;

}

Page 15: Java Introduction to JNI Prepared by Humaira Siddiqui.

Writing JNI Methods -10

5. Compile the C/C++ code into a library (a DLL if your code will run under Windows).

If you use C++ Builder to compile your library under Windows,

make sure you create a DLL project and then add the C/C++

file to it (e.g. HelloWorld.c). You'll need to add the following to

your compiler's include path:

\javadir\include

\javadir\include\win32

Be sure to name your project c_library so the DLL it creates will

be named c_library.dll.

Page 16: Java Introduction to JNI Prepared by Humaira Siddiqui.

Writing JNI Methods -11

5. If you are compiling your C library under Windows using Visual C++, you do the following:

cl -Ic:\javadir\include -Ic:\javadir\include\win32

-LD HelloWorld.c -Fec_library.dll

(Note: entire command must be on one line)This creates the file, c_library.dll

Page 17: Java Introduction to JNI Prepared by Humaira Siddiqui.

Writing JNI Methods -12

5. If you are compiling your C library under Solaris, you do the following:

cc -G -I/javadir/include -I/javadir/include/solaris \ HelloWorld.c -o c_library.so

This creates the file, c_library.so

Page 18: Java Introduction to JNI Prepared by Humaira Siddiqui.

Writing JNI Methods -13

6. Run the Java class (main method). Switch to the directory just above the "com" directory and run the following:

java -classpath . com.cexp.wms.jni.examples.HelloWorld

You should see "Hello world! I'm here!" appear on the screen!

If you see a "java.lang.UnsatisfiedLinkError" error message,

then Java couldn't find your shared library. Either add the

directory your library (DLL) resides in to your Java runtime

library path OR copy the library file to the working directory of

your Java program.

Page 19: Java Introduction to JNI Prepared by Humaira Siddiqui.

JNI and Fortran

You can invoke Fortran code from your Java applications To do that, you write some Java JNI code to invoke C/C++

methods in a DLL, and write those C/C++ methods to invoke the Fortran code you want to run

It sounds complicated, but the runtime overhead isn’t as bad as you might think

JNI(Java program)

C/C++ “bridge”DLL

Fortran program

Page 20: Java Introduction to JNI Prepared by Humaira Siddiqui.

JNI Summary

JNI can be a little tedious the first time you try it, but in the scheme of things it isn't that complicated.

Use JNI to leverage existing code (that you don't want to port to

Java) Solve problems that Java isn't suited for (e.g., when you

need the speed of C or assembler, or when you need to write low level code to communicate directly with hardware