You are on page 1of 40

1Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Mixed-Language
Development: Leveraging
Native Code from Java CON3408
Darryl Gove
Senior Principal Software Engineer

2Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Insert Picture Here

Outline
Overview of JNI
Mixed Java/native debugging
Mixed Java/native performance
Other solutions

3Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Overview of JNI
Insert Picture Here

4Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Java Native Interface

Call Java code from native code


Call native code from Java
Supporting routines

Data conversion etc.

5Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Why Call Native Code

Existing code base


Legacy application
Hardware features
Performance?!?

6Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Using JNI
Insert Picture Here

7Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Calling Native Code

class myApp
{
private native void go();

Native code
to be called

public static void main(String[] args)


{
System.loadLibrary("myLib");
new myApp().go();
Library containing
}
}
8Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Call native code

native code

Finding Libraries

Automatically qualifies name for platform

e.g. myLib becomes libmyLib.so

Searches default search path


Find libraries:

Environment: LD_LIBRARY_PATH=`pwd` is a hack

Command line: -Djava.library.path=`pwd`

Programmatically...

9Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Programmatically Loading Library


class myApp
{
private native void go();

Current directory

public static void main(String[] args)


{
String file = System.getProperty("user.dir");
file+="/libmyLib.so";
System.load(file);
Actual name
new myApp().go();
of library
}
}
10Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Load library

Writing the Native Code

Compile Java code


Generate native header file from class
Include header into C source
Compile library including Java SDK header files

11Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Generating C header files


$ javac myApp.java
$ javah -jni myApp
Compile class

Generate header file

12Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Generated Header File


#include <jni.h>
#ifdef __cplusplus
extern "C" {
#endif

Include JNI
header file
C linkage

JNIEXPORT void JNICALL Java_myApp_go (JNIEnv *, jobject);


#ifdef __cplusplus
}
#endif

13Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Declaration of
native function

Breaking Down the Header File


#include <jni.h>
#ifdef __cplusplus
extern "C" {
#endif

Scope the function


for export

Define calling
convention

JNIEXPORT void JNICALL Java_myApp_go (JNIEnv *, jobject);


#ifdef __cplusplus
}
Mangled name
#endif
for called function
Return type

14Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Pointer to
Java environment

Pointer to
calling object

Writing the Native code


#include <stdio.h>

Include header
file

#include "myApp.h"
Write native
code

JNIEXPORT void JNICALL


Java_myApp_go(JNIEnv* jenv, jobject job)
{
printf("Gone...\n");
}

15Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Compiling the Native Code


$ cc -G -Kpic -g -O -o libmyLib.so myLib.c \
-I/usr/java/include -I/usr/java/include/solaris
Generate library: -G
Position independent code: -Kpic
Debug code: -g
Optimised code: -O
Path to include files: -I

Need to include platform specific headers

16Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Parameter Passing
Insert Picture Here

17Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Parameter Passing: Java Side

Function prototype
class Total
{
private native double sum(double[] array,int len);
void work()
{ double[] array=new double[2048];
for (int i=0; i<2048; i++) { array[i]=i*15.0; }
System.out.print("Total = ");
System.out.println( sum(array, 2048) );
}
public static void main(String[] args)
Function call
{ System.loadLibrary(Total);
new Total().work(); }
}
18Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Parameter Passing: C Header File


#include <jni.h>
#ifdef __cplusplus
extern "C" {
#endif

Function prototype

JNIEXPORT jdouble JNICALL Java_Total_sum


(JNIEnv *, jobject, jdoubleArray, jint);
#ifdef __cplusplus
}
#endif

19Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Parameter Passing
JNIEXPORT jdouble JNICALL Java_Total_sum
(JNIEnv * jenv, jobject job, jdoubleArray jd, jint len)
{
Copy Java array
double total = 0;
to native type
double* d =(*jenv)->GetDoubleArrayElements(jenv,jd,0);
for (int i=0; i<len; i++) { total += d[i]; }
(*jenv)->ReleaseDoubleArrayElements(jenv,jd,d,0);
return total;

Copy native array


back to Java

}
Return result

20Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Debugging Mix
Java/Native Applications

21Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Insert Picture Here

Debugging: Starting to debug


$ dbx Total.class
Debug target is "Total.class"
Will be debugging "Total"
Reading java
(dbx) stop in Total.main
(2) java stop in Total.main(java.lang.String[])
(dbx) run
stopped in Total.main at line 18 in file "Total.java"
18
System.loadLibrary("Total");

22Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Debugging: Debugging Java Code


(dbx) stop at Total.java:10
(3) java stop at "Total.java":10
(dbx) cont
stopped in Total.compute at line 10 in file "Total.java"
10
array[i]=i*15.0;
(dbx) print i
int i = 0

23Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Debugging: Debugging Native Code


(dbx) stop at Total.java:13
(4) java stop at "Total.java":13
(dbx) cont
Total = stopped in Total.compute at line 13 in file
"Total.java"
13
System.out.println( sum(array, 2048) );
(dbx) step
t@2 (l@2) stopped in Java_Total_sum (optimized) at line 7
in file "Total.c"
7
double* d =(*jenv)->
GetDoubleArrayElements(jenv,jd,0);
24Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Performance Tuning
Mixed Java/Native
Applications

25Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Insert Picture Here

Profiling Mixed Code


$ collect -j on java -Djava.library.path=`pwd` PerfTotal
Creating experiment database test.1.er ...
Total = 3.144192E7
$ analyzer test.1.er
View profile

26Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Gather profile

Function Profile

Native code

Java code

27Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Mixed Call Tree

Java code

C code

28Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Java Source Code

Call where
time spent

29Copyright 2012, Oracle and/or its affiliates. All rights reserved.

C Source Code

Cost of converting
to native data

Line where
time spent

30Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Cost of converting
data back to Java

Other Solutions
Insert Picture Here

31Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Other Solutions

JNI

Enables calling of native code

Requires wrapper code

Java Native Access (JNA), Java Native Runtime (JNR)

Built on JNI

Direct calls to libraries

32Copyright 2012, Oracle and/or its affiliates. All rights reserved.

JNA Example: Java Code


import com.sun.jna.Library;
import com.sun.jna.Native;

Load library
class Len{
public interface LLib extends Library
{
LLib INSTANCE = (LLib)Native.loadLibrary("Length", LLib.class);
int textLen(String text);
}
Declare functions

void work()
{ System.out.println(LLib.INSTANCE.textLen(Hello)); }
public static void main(String[] args){new Len().work(); }
}

Call function
33Copyright 2012, Oracle and/or its affiliates. All rights reserved.

JNA Example: C Code


#include <stdio.h>
int textLen(char * text)
{
int count=0;
printf("Input Text = %s",text);
while (*text!=0)
{
count++;
text++;
}
printf("Length = %i\n",count);
return count;
}

34Copyright 2012, Oracle and/or its affiliates. All rights reserved.

JNA Example: Compile and Run


$ javac -cp '.:jna.jar' Len.java
$ cc -g -O -G -Kpic -o libLength.so length.c
$ java -cp '.:jna.jar' Len
Input Text = HelloLength = 5
5

35Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Function Profile

Was 12s for JNI

36Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Concluding Remarks
Insert Picture Here

37Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Concluding Remarks: JNI

JNI

Allows reuse of existing code

Performance impact due to data type conversion

JNA/JNR

Make process easier

Potential increased performance hit

38Copyright 2012, Oracle and/or its affiliates. All rights reserved.

Concluding Remarks: Tools

Oracle Solaris Studio

Debug of mixed language applications

Profiling of mixed language applications

39Copyright 2012, Oracle and/or its affiliates. All rights reserved.

40Copyright 2012, Oracle and/or its affiliates. All rights reserved.

You might also like