Lecture 6 NDK Integration JNI This work is

  • Slides: 32
Download presentation
Lecture 6 - NDK Integration (JNI) This work is licensed under the Creative Commons

Lecture 6 - NDK Integration (JNI) This work is licensed under the Creative Commons Attribution 4. 0 International License. To view a copy of this license, visit http: //creativecommons. org/licenses/by/4. 0/ or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.

Arrays � Java arrays - reference type in JNI � JNI treats primitive arrays

Arrays � Java arrays - reference type in JNI � JNI treats primitive arrays and object arrays differently � Primitive arrays contain primitives � Object arrays contain class instances or other arrays � Object[] and int[][] are object arrays � jarray and subtypes (jint. Array, jobject. Array) Laura Gheorghe, Petre Eftime 2

New Array � New<Type>Array etc. where Type is Int, Char, Boolean, jint. Array java.

New Array � New<Type>Array etc. where Type is Int, Char, Boolean, jint. Array java. Array = env->New. Int. Array(10); � In case of memory overflow � Function returns NULL � Exception is thrown in the VM � Native code should be stopped Laura Gheorghe, Petre Eftime 3

Accessing Array Elements using a Copy � Copy Java array into C array or

Accessing Array Elements using a Copy � Copy Java array into C array or obtain a direct pointer to the array elements � Copy Java array into C array � Get<Type>Array. Region jint native. Array[10]; env->Get. Int. Array. Region(java. Array, 0, 10, native. Array); � Make changes on the array elements � Copy C array back into Java array � Set<Type>Array. Region env->Set. Int. Array. Region(java. Array, 0, 10, native. Array); � Performance problem for big array size Laura Gheorghe, Petre Eftime 4

Operating on Direct Pointer � Obtain a direct pointer to the array elements when

Operating on Direct Pointer � Obtain a direct pointer to the array elements when possible � Get<Type>Array. Elements jint* native. Direct. Array; jboolean is. Copy; native. Direct. Array = env->Get. Int. Array. Elements(java. Array, &is. Copy); � is. Copy - the C array points to a copy or a pinned array in heap � Returns NULL if operation fails Laura Gheorghe, Petre Eftime 5

Releasing a Direct Pointer � Release array returned by Get<Type>Array. Elements � Release<Type>Array. Elements

Releasing a Direct Pointer � Release array returned by Get<Type>Array. Elements � Release<Type>Array. Elements env->Release. Int. Array. Elements(java. Array, native. Direct. Array, 0); � Last parameter - release mode � 0 - copy back content, free native array � JNI COMMIT - copy back content, do not free native array (update Java array) � JNI ABORT - do not copy back content, free native array � Get. Array. Length � Get/Release. Primitive. Array. Critical Laura Gheorghe, Petre Eftime 6

Object Array � Create new object array � New. Object. Array jobject. Array arr

Object Array � Create new object array � New. Object. Array jobject. Array arr = env->New. Object. Array(size, java. Class, NULL); � Params: length, class and initialization value � Obtain an element from an object array � Get. Object. Array. Element � Cannot obtain all object elements jstring js = (jstring)env-> Get. Object. Array. Element(arr, i); � Update an element in an object array � Set. Object. Array. Element env->Set. Object. Array. Element(arr, i, js); Laura Gheorghe, Petre Eftime 7

NIO Operations � Native I/O - buffer management, scalable network and file I/O �

NIO Operations � Native I/O - buffer management, scalable network and file I/O � Better performance - deliver data between native and Java app � Create a direct byte buffer to be used in the Java app � New. Direct. Byte. Buffer unsigned char* buffer = (unsigned char*) malloc(1024); jobject direct. Buffer; direct. Buffer = env->New. Direct. Byte. Buffer(buffer, 1024); � Based on a native byte array � Obtain native byte array from Java byte buffer � Get. Direct. Buffer. Address unsigned char* buffer; buffer = (unsigned char*) env->Get. Direct. Buffer. Address (direct. Buffer); � The direct byte buffer can also be created in the Java app Laura Gheorghe, Petre Eftime 8

Field Types � In Java: static fields and instance fields � Each instance has

Field Types � In Java: static fields and instance fields � Each instance has its own copy of the instance fields private String instance. Field = "Instance Field"; � All instances share the same static fields private static String static. Field = "Static Field"; � JNI functions for both types of fields Laura Gheorghe, Petre Eftime 9

Get Field ID � Obtain class object from instance � Get. Object. Class jclass

Get Field ID � Obtain class object from instance � Get. Object. Class jclass cl = env->Get. Object. Class(instance); � Obtain field ID of an instance field � Get. Field. ID jfield. ID instance. Field. Id; instance. Field. Id = env->Get. Field. ID(cl, "instance. Field", "Ljava/lang/String; "); � Last parameter - field descriptor � Obtain field ID of static field � Get. Static. Field. ID jfield. ID static. Field. Id; static. Field. Id = env->Get. Static. Field. ID(cl, "static. Field", "Ljava/lang/String; "); Laura Gheorghe, Petre Eftime 10

Get Fields � Obtain an instance field � Get<Type>Field jstring instance. Field; instance. Field

Get Fields � Obtain an instance field � Get<Type>Field jstring instance. Field; instance. Field = env->Get. Object. Field(instance, instance. Field. Id); � Obtain a static field � Get. Static<Type>Field jstring static. Field; static. Field = env->Get. Static. Object. Field(cl, static. Field. Id); � Type = Object, Primitive type � Return NULL in case of memory overflow � Performance overhead � Recommended to pass parameters to native methods Laura Gheorghe, Petre Eftime 11

Types of Methods � In Java: instance and static methods � Instance method private

Types of Methods � In Java: instance and static methods � Instance method private String instance. Method() { return "Instance Method"; } � Static method private static String static. Method() { return "Static Method"; } � JNI functions to access both types Laura Gheorghe, Petre Eftime 12

Get Method ID � Obtain method ID of an instance method � Get. Method.

Get Method ID � Obtain method ID of an instance method � Get. Method. ID jmethod. ID instance. Method. Id; instance. Method. Id = env->Get. Method. ID(cl, "instance. Method", "()Ljava/lang/String; "); � Last parameter - method descriptor (signature) � Obtain method ID of a static method � Get. Static. Method. ID jmethod. ID static. Method. Id; static. Method. Id = env->Get. Static. Method. ID(cl, "static. Method", "()Ljava/lang/String; "); Laura Gheorghe, Petre Eftime 13

Get Methods � Call instance method � Call<Type>Method jstring instance. Method. Result; instance. Method.

Get Methods � Call instance method � Call<Type>Method jstring instance. Method. Result; instance. Method. Result = env->Call. Object. Method (instance, instance. Method. Id); � Call static method � Call. Static<Type>Field jstring static. Method. Result; static. Method. Result = env->Call. Static. Object. Method(cl, static. Method. Id); Type = Void, Object, Primitive type � Specify method arguments after method ID � Return NULL in case of memory overflow � Performance overhead � � Minimize transitions between Java and native code Laura Gheorghe, Petre Eftime 14

Field & Method Descriptors Java Type Signature Boolean Z Byte B Char C Short

Field & Method Descriptors Java Type Signature Boolean Z Byte B Char C Short S Int I Long J Float F Double D fully-qualified-class Lfully-qualified-class type[] [type method type (arg-type)ret-type Use javap to obtain descriptors associated to a Java class Laura Gheorghe, Petre Eftime 15

Catch Exceptions � Handling exceptions is important in Java � VM catches exception, clears

Catch Exceptions � Handling exceptions is important in Java � VM catches exception, clears exception and executes handling block � In native code developers must implement exception handling flow � Catch an exception generated while calling a Java method � Exception. Occurred env->Call. Void. Method(instance, method. ID); jthrowable ex = env->Exception. Occurred(); if (ex != NULL) { env->Exception. Clear(); /* Handle exception here */ } Laura Gheorghe, Petre Eftime 16

Throw Exceptions � Native code can throw Java exceptions � First obtain exception class

Throw Exceptions � Native code can throw Java exceptions � First obtain exception class � Throw exception � Throw. New jclass cl = env->Find. Class ("java/lang/Null. Pointer. Exception"); if (cl != NULL) { env->Throw. New(cl, "Message"); } � Does not automatically stop native method and control to exception handler � Should free resources and transfer return Laura Gheorghe, Petre Eftime 17

References � The VM tracks object references and garbage collects the ones that are

References � The VM tracks object references and garbage collects the ones that are not referenced � JNI allows native code to manage object references and lifetimes � 3 types of references: local, global and weak global Laura Gheorghe, Petre Eftime 18

Local References � Most JNI functions return local references � Cannot be cached and

Local References � Most JNI functions return local references � Cannot be cached and reused in subsequent invocations � Lifetime limited to the native method - freed when method returns � Minimum 16 local references for the native code in the VM � Free local references while making memory-intensive operations � Manually free local reference � Delete. Local. Ref jclass cl = env->Find. Class("java/lang/String"); env->Delete. Local. Ref(cl); Laura Gheorghe, Petre Eftime 19

Global References � Valid during subsequent invocations of the native method � Until explicitly

Global References � Valid during subsequent invocations of the native method � Until explicitly freed � Create new global reference � New. Global. Ref jclass local. Cl = env->Find. Class("java/lang/String"); jclass global. Cl = env->New. Global. Ref(local. Cl); env->Delete. Local. Ref(local. Cl); � Delete global reference when no longer used � Delete. Global. Ref env->Delete. Global. Ref(global. Cl); � Can be used by other native methods or native Laura Gheorghe, Petre Eftime threads 20

Weak Global References � Valid during subsequent invocations of the native method � The

Weak Global References � Valid during subsequent invocations of the native method � The object can be garbage collected � Create new weak global reference � New. Weak. Global. Ref jclass weak. Global. Cl; weak. Global. Cl = env->New. Weak. Global. Ref(local. Cl); Laura Gheorghe, Petre Eftime 21

Weak Global References � Verify if the reference is still pointing to an instance

Weak Global References � Verify if the reference is still pointing to an instance � Is. Same. Object if (env->Is. Same. Object(weak. Global. Cl, NULL) == JNI_FALSE){ /* Object is still live */ } else { /* Object is garbage collected */ } � Delete weak global reference � Delete. Weak. Global. Ref env->Delete. Weak. Global. Ref(weak. Global. Cl); Laura Gheorghe, Petre Eftime 22

Threads � Multithreaded environment � Threads vs. references � Local references valid only in

Threads � Multithreaded environment � Threads vs. references � Local references valid only in the thread context executing the native method � Local references cannot be shared between multiple threads � Global references can be shared between multiple threads � Threads vs. JNIEnv � Interface pointer valid only in the thread executing the method � Cannot be cached and used by other threads Laura Gheorghe, Petre Eftime native 23

Native Threads � Use threads for running tasks in parallel � Linux threads, scheduled

Native Threads � Use threads for running tasks in parallel � Linux threads, scheduled by the kernel � Started from managed code with Thread. start � Can also be started with pthread_create � Native threads not known by the VM until they are attached � No JNIEnv � Cannot make JNI calls Laura Gheorghe, Petre Eftime 24

Native Threads � First attach native thread to the VM � Attach. Current. Thread

Native Threads � First attach native thread to the VM � Attach. Current. Thread Java. VM* cached. Jvm; JNIEnv* env; cached. Jvm->Attach. Current. Thread(&env, NULL); � Obtain a JNIEnv interface pointer for the current thread java. lang. Thread object added to main Thread. Group � Last argument: Java. VMAttach. Args structure - can specify � other thread group � Attach. Current. Thread. As. Daemon � After communication with the Java app, detach from VM � Detach. Current. Thread cached. Jvm->Detach. Current. Thread(); Laura Gheorghe, Petre Eftime 25

Synchronization � Synchronization using monitors based on Java objects � Only one thread can

Synchronization � Synchronization using monitors based on Java objects � Only one thread can hold a monitor at a time � Acquire a monitor � Monitor. Enter env->Monitor. Enter(obj); � obj is a Java object � If another thread owns the monitor, waits until it’s released � If no other thread owns the monitor, becomes owner, entry counter = 1 � If the current thread owns the monitor, increments the entry counter Laura Gheorghe, Petre Eftime 26

Synchronization � Release monitor � Monitor. Exit env->Monitor. Exit(obj); � The current thread must

Synchronization � Release monitor � Monitor. Exit env->Monitor. Exit(obj); � The current thread must be the owner of the monitor � Entry counter is decremented � When counter = 0, the current thread releases the Laura Gheorghe, Petre Eftime monitor 27

Standard JNI vs. Android JNI � All JNI 1. 6 features are supported by

Standard JNI vs. Android JNI � All JNI 1. 6 features are supported by Android JNI � Exception: Define. Class not implemented � No Java bytecodes or class files in Android � Not useful � JNI does not include proper error checks � Android includes Check. JNI mode � Performs series of checks before the actual JNI function called � Enable Check. JNI from adb shell � Enabled by default on emulator Laura Gheorghe, Petre Eftime is 28

Check. JNI � Attempt to allocate negative-sized arrays � Passing a bad pointer(jobject, jclass,

Check. JNI � Attempt to allocate negative-sized arrays � Passing a bad pointer(jobject, jclass, jarray, jstring) to a JNI call � Passing a NULL pointer to a JNI call when argument should not be NULL � Passing a class name not correctly specified to a JNI call � Making a JNI call in a critical region � Passing invalid arguments to New. Direct. Byte. Buffer � Making a JNI call while an exception is pending Laura Gheorghe, Petre Eftime 29

Check. JNI � Using JNIEnv* in the wrong thread � Using NULL, wrong type

Check. JNI � Using JNIEnv* in the wrong thread � Using NULL, wrong type field ID, static/instance mismatch � Using invalid method ID, incorrect return type, static/instance mismatch, invalid instance/class � Using Delete. Global/Local. Ref on the wrong reference � Passing a bad release mode, other than 0, JNI_COMMIT, JNI_ABORT � Returning incompatible type from native method � Passing invalid UTF-8 sequence to a JNI Laura Gheorghe, Petre Eftime call 30

Bibliography � http: //www. soi. city. ac. uk/~kloukin/IN 2 P 3/material/jni. pd f �

Bibliography � http: //www. soi. city. ac. uk/~kloukin/IN 2 P 3/material/jni. pd f � http: //docs. oracle. com/javase/6/docs/technotes/guides/ jni/spec/jni. TOC. html � http: //download. java. net/jdk 8/docs/technotes/guides/jni /spec/functions. html � http: //developer. android. com/training/articles/perfjni. html � Onur Cinar, Pro Android C++ with the NDK, Chapter 3 � Sylvain Ratabouil, Android NDK, Beginner’s Guide, Chapter 3 Laura Gheorghe, Petre Eftime 31

Keywords � Primitive array � Field/method descriptor � Object array � Catch/throw exception �

Keywords � Primitive array � Field/method descriptor � Object array � Catch/throw exception � Direct pointer � Local/global/weak global � Native I/O � Static/instance fields � Static/instance methods � Field/method ID references � Native threads � Monitor � Check. JNI Laura Gheorghe, Petre Eftime 32