Java native interface jni
This presentation is the property of its rightful owner.
Sponsored Links
1 / 23

Java Native Interface (JNI) PowerPoint PPT Presentation


  • 213 Views
  • Uploaded on
  • Presentation posted in: General

Java Native Interface (JNI). Phil Pratt-Szeliga Syracuse University. JNI Overview. JNI allows a developer to interop with arbitrary C/C++ code The managed to native transition can take time, so don’t expect a performance enhancement from, say, repeatedly incrementing an integer

Download Presentation

Java Native Interface (JNI)

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Java native interface jni

Java Native Interface (JNI)

Phil Pratt-Szeliga

Syracuse University


Jni overview

JNI Overview

  • JNI allows a developer to interop with arbitrary C/C++ code

  • The managed to native transition can take time, so don’t expect a performance enhancement from, say, repeatedly incrementing an integer

  • With JNI you need to have a .dll built for Windows and a .so built for Linux (and I guess a .so for Mac).

    • Your build process needs to be able to built the .dllon Windows and the .so on Linux and then possibly pack it in the jar file

    • You need to build two separate dll’s and so’s to cover 32bit and 64bit platforms.


Calling jni code from java

Calling JNI Code From Java

package edu.syr.distobjects.jniexample;

public class FirstExample{

//it is good to make public wrappers around

//native methods

public void printString(String str){

doPrintString(str);

}

//the native keyword it present here

private native void doPrintString(String str);

}


Creating the c c headers

Creating the C/C++ Headers

  • Directory structure:

    • netbeans_root

      • build

        • classes

          • edu

            • syr

              • distobjects

                • jniexample

      • src

        • edu

          • syr

            • distobjects

              • jniexample

    • native (you need to make this directory)

  • Linux:

    • $ cd /path/to/netbeans_root/build/classes

    • $ javahedu.syr.distobjects.jniexample.FirstExample

    • $ mv edu_syr_distobjects_jniexample_FirstExample.h../../native/

  • Windows:

    • $ cd \path\to\netbeans_root\build\classes

    • $ “C:\Program Files (x86)\Java\jkd1.6.0_26\bin\javah”edu.syr.distobjects.jniexample.FirstExample

    • $ move edu_syr_distobjects_jniexample_FirstExample.h..\..\native\


  • Created c c header

    Created C/C++ Header

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

    #include <jni.h>

    /* Header for class edu_syr_distobjects_jniexample_FirstExample */

    #ifndef _Included_edu_syr_distobjects_jniexample_FirstExample

    #define _Included_edu_syr_distobjects_jniexample_FirstExample

    #ifdef __cplusplus

    extern "C" {

    #endif

    /*

    * Class: edu_syr_distobjects_jniexample_FirstExample

    * Method: doPrintString

    * Signature: (Ljava/lang/String;)V

    */

    JNIEXPORT void JNICALL Java_edu_syr_distobjects_jniexample_FirstExample_doPrintString

    (JNIEnv *, jobject, jstring);

    #ifdef __cplusplus

    }

    #endif

    #endif


    Copy prototype to cpp file

    Copy Prototype to .cpp File

    #include “edu_syr_distobjects_jniexample_FirstExample.h”

    JNIEXPORT void JNICALL Java_edu_syr_distobjects_jniexample_FirstExample_doPrintString

    (JNIEnv* env, jobjectthis_obj, jstringstr)

    {}

    Note I gave names to env, this_obj, and str.

    env: Every JNI function is passed a JNIEnv pointer

    this_obj: Represents the managed “this” pointer

    str: The only argument to the method in the Java code


    Implement a cout

    Implement a cout

    #include “edu_syr_distobjects_jniexample_FirstExample.h”

    #include <iostream>

    JNIEXPORT void JNICALL Java_edu_syr_distobjects_jniexample_FirstExample_doPrintString

    (JNIEnv * env, jobjectthis_obj, jstringstr)

    {

    intlen = (*env)->GetStringLength(env, str);

    char * nstr = new char[len];

    (*env)->GetStringUTFRegion(env, str, 0, len, nstr);

    std::cout << nstr << std::endl;

    delete [] nstr;}


    Build the dll

    Build the .dll

    Put this in cl_options.txt (on one line)

    /I"C:\Program Files\Java\jdk1.6.0_26\include“

    /I"C:\Program Files\Java\jdk1.6.0_26\include\win32“

    FirstExample.cpp

    /DLL

    /OUT:first_example.dll

    /MACHINE:X64

    Make a native_build.bat (keep lines separate)

    "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" amd64

    cl @cl_options.txt


    Load the dll in java

    Load the .dll in Java

    package edu.syr.distobjects.jniexample;

    import java.io.File;

    public class FirstExample {

    //called during first initialization of FirstExampleclass

    static {

    //load requires an absolute path and this method ensures that File file = new File(“first_example.dll”);

    System.load(file.getAbsolutePath());

    }

    public void printString(String str){

    doPrintString(str);

    }

    private native void doPrintString(String str);

    }


    Distributing the dll with a jar

    Distributing the .dll with a .jar

    In netbeans if you create a package (folder) and then have your build process place the .dll in the folder, it will be included in the .jar

    public class BinaryLoader {

    public void extractBinary(String filename) throws Exception {

    String path = "/edu/syr/distobjects/jniexample/native/"+filename;

    InputStreamis = BinaryLoader.class.getResourceAsStream(path);

    OutputStreamos = new FileOutputStream(filename);

    while(true){

    byte[] buffer = new byte[32*1024];

    intlen = is.read(buffer);

    if(len== -1) { break; }

    os.write(buffer, 0, len);

    }

    os.flush(); os.close(); is.close();

    }

    }


    Saving state in a cpp

    Saving State In a cpp

    • You can save state in a high performance way by using static globals in a cpp

      • But all instances of a class will share that state

    • A slower way is to save state back to a Java Field

      void setLongField(JNIEnv * env, jobjectobj, long value){

      jclassthis_class = (*env)->GetObjectClass(env, obj);

      jfieldIDfid = (*env)->GetFieldID(env, this_class, “m_FieldName”, "J");

      (*env)->SetLongField(env, obj, fid, value);

      }


    Java type strings

    Java Type Strings

    • Previously we passed in “J” into GetFieldID

      • B = byte

      • C = char

      • D = double

      • F = float

      • I = int

      • J = long

      • S = short

      • V = void

      • Z = boolean

      • Ljava/lang/String; = String

      • Ljava/lang/Object; = Object

      • Lfully/qualified/Classname = fully.qualified.Classsname

      • [B – single dimensional byte array

      • [[B – two dimensional byte array

      • [Ljava/lang/String; - one dimensional string array


    Calling a java method

    Calling a Java Method

    jbyteArraylist_get(JNIEnv* env, jobjectlist, int index){

    jmethodID mid;

    jclasslist_interface = (*env)->FindClass(env, "java/util/List");

    mid = (*env)->GetMethodID(env, list_interface, "get", "(I)Ljava/lang/Object;");

    return (*env)->CallObjectMethod(env, list, mid, index);

    }

    • “java/util/List” – interface or class name

    • “get” – method name

    • “(I)Ljava/lang/Object;” – a method that accepts an int as a parameter and returns a Ljava/lang/Object;

    • jbyteArray – a byte[]

    • In Java, the list was declared as:

      • List<byte[]> list;


    Jni field functions

    JNI Field Functions

    • Based on Field Type:

      • GetObjectField

      • GetBooleanField

      • GetByteField

      • GetCharField

      • GetShortField

      • GetIntField

      • GetLongField

      • GetFloatField

      • GetDoubleField

    • Corresponding setters are like:

      • SetObjectField


    Jni method invocation functions

    JNI Method Invocation Functions

    • Based on return type:

      • CallObjectMethod

      • CallBooleanMethod

      • CallByteMethod

      • CallCharMethod

      • CallShortMethod

      • CallIntMethod

      • CallLongMethod

      • CallFloatMethod

      • CallDoubleMethod

      • CallVoidMethod


    Jni array functions

    JNI Array Functions

    • Based on Array Type:

      • GetBooleanArrayElements

      • GetByteArrayElements

      • GetCharArrayElements

      • GetShortArrayElements

      • GetIntArrayElements

      • GetLongArrayElements

      • GetFloatArrayElements

      • GetDoubleArrayElements

    • Corresponding releases need to be called like:

      • ReleaseBooleanArrayElements

    • Array length:

      • GetArrayLength

    • Arrays of objects: can only get one at a time because you can’t know the size of an object to store in a regular C style array

      • GetObjectArrayElement

      • SetObjectArrayElement


    Example of jni array copy

    Example of JNI Array Copy

    JNIEXPORT void JNICALL Java_edu_syr_pcpratts_rootbeer_ArrayMemory_doWriteIntArray

    (JNIEnv *env, jobjectthis_obj, jintArray array, jlong ref, jintlen){

    char * dest = (char *) ref;

    jint* narray = (*env)->GetIntArrayElements(env, array, JNI_FALSE);

    memcpy(dest, narray, len*sizeof(int));

    (*env)->ReleaseIntArrayElements(env, array, narray, JNI_ABORT);

    }

    jlong ref was previously allocated in the C++ code using new. You can easily save any pointer in C++ in a Java field using a long. ref was saved as a member field in the Java class.

    JNI_FALSE and JNI_ABORT have to deal with memory pinning and copying back of the change array into the java runtime. I can’t find a reference right now for these


    Real world usage of jni

    Real World Usage of JNI

    • Rootbeer: tool to make it easier to program GPUs from Java

      • All the GPU vendors give C bindings to their API.

      • API allows to:

        • Create/Destroy GPU memory

        • Copy from CPU memory to GPU memory

        • Query how many sub-processors a GPU has

        • Compile CUDA programs to a binary for the GPU

        • Launch jobs onto the GPU


    Java native interface jni

    GPUs

    • GPU = Graphics Processing Unit

      • Specialized processor originally made only to feed Monitor with byte buffer

      • A device has on the order of 512 cores!

      • Each core is quite simple and slow:

        • No branch prediction or out of order execution

        • Clock rate is 1.3 Ghz range

      • Groups of 32 cores all have to be doing the same thing

        • They share instruction fetch hardware

      • Really hard to program

        • Need to learn special programming language to execute on the GPU (CUDA)

        • Need to manually serialize all of your complex classes in C/C++ to arrays (this may have changed recently…need to check)

        • Need to find huge amounts of parallelism in original program to get a speedup

          • Getting a speedup is the only reason to use a GPU

          • Naïve Dense matrix multiplication can easily be sped up 100X


    Rootbeer

    Rootbeer

    • Rootbeer allows the developer to program in Java and it automatically:

      • Creates a CUDA program from analyzing Java Bytecode (with the help of the Soot Java Optimization Framework)

      • Creates Java Bytecode that can (de)serialize CPU memory to GPU memory in a high performance manner

      • Gives a Java interface for automatically launching these jobs on the GPU


    Rootbeer status

    Rootbeer Status

    • By the end of summer 2012 there will be a public release of Rootbeer available for people to use

      • We currently have a non-optimized version that is highly tested:

        • 20K SLOC product code

        • 5k SLOC test code

        • All tests pass covering all aspects of the Java programming language except:

          • Sleeping while inside a monitor

          • Reflection

          • Dynamic methods in Java (recently added to Java, makes static analysis really hard)

          • Java Code that uses JNI…

          • Garbage collection


    Questions

    Questions?


    References

    References

    http://dev.kanngard.net/Permalinks/ID_20050509144235.html

    http://docs.oracle.com/javase/1.4.2/docs/guide/jni/spec/functions.html

    http://java.sun.com/docs/books/jni/html/jniTOC.html


  • Login