JNI : Java Glossary


nuts and bolts  JNI
acronym JNI (Java Native Interface). It comes as part of the JDK (Java Development Kit). How you write C/ C++/assembler code native methods callable from Java. It also lets C/C++ code call Java methods. Microsoft J++ does not support JNI. Before you get too deeply into JNI check out the exec function. Also check if JConfig has what you need. It may do what you want with much less hassle. Also check out XFunction which lets you do JNI without writing any of that complicated JNI C code.
Tying Java and C/C++ together is a messy business. Unless you are constrained by something such as:
  • legacy code without source
  • proprietary specialty library
  • platform-specific code
  • device drivers
then you will likely be happiest converting everything to one language. In any case, you want to keep the corpus callosum between the two languages as small as possible with as little traffic as possible. In other words, when in Java, attempt to stay in Java as long as possible. When in C/C++, attempt to stay as long as possible in C/C++. Share as little data as possible back and forth. Keep the formats of shared data as minimal as possible.
Introduction Using JNI in Applets The Old Netscape Problem
The Overall Process System.load vs System.loadLibrary The Old Netscape Solution
Some general JNI tips Windows loadLibrary The Old Netscape Recipe
C/C++ Primitive Types Solaris and Linux loadLibrary Strategy
JNI Manipulator Functions Macintosh loadLibrary 64-bit
Typical JNI C Code DLL in the Jar Alternatives
Typical JNI C++ Code File Naming Conventions Books
Compiling JNI C/C++ Code Exceptions Learning More
JNI and Assembler Threads Links
JNI Example Code Reflection


JNI is how you write C/C++/assembler code native methods callable from Java. It also lets C/ C++ code call Java methods.

You can’t directly manipulate or create C++ objects from Java. You need to write native method implementation code in C++ to allow java objects and methods to indirectly create and manipulate the C++ objects. Your C++ code has to do the C++ object creating and manipulating based on clues passed from Java by native methods and parameters.

The Overall Process

  1. If you need to use JNI from an Applet, order a certificate well in advance. See Signed Applet.
  2. Put all your classes in a package. Package-less classes are just for tiny toy programs.
  3. Write a Java class containing a native method something like this Glue.java:
  4. Compile Glue.java with javac.exe in the usual way. This step is very important. You must have a clean compile before using javah.exe.
  5. Generate the Glue.h header file containing the prototypes of the C/C++ methods you must write with:
    javah.exe -jni -o Glue.h com.mindprod.JNIExper.Glue
  6. Write a C or C++ class something like this Glue.c using the code in glue.h as a template.
  7. Link that C code and any assembler code it calls into a DLL (Dynamic Link Library). The DLL may contain methods from many different classes.
  8. Pre-install the DLL on the java.library.path i.e. on the browser’s classpath or path, e. g. J:\Program Files\java\jdk1.8.0_112\ \jre\bin\ext (for the JDK 1.8.0 plug-in), WINNT\java\trustlib (for Internet Explorer), Program Files\Netscape\Communicator\java\classes (for Netscape 8.0).
  9. You can’t change DLLs (Dynamic Link Libraries) to a new version without rebooting, not even the disk copy, let alone the RAM (Random Access Memory) image. Java can change code on the fly without so much as stopping the program. Surely Microsoft could work out a method to change a DLL that did not require such drastic measures. Some Unix machines run for years without rebooting. To replace a DLL with a new one, you must use the inuse utility to allow you to replace the DLL and then reboot to clear the in-RAM copy.

    inuse test.dll C:\winnt\system32\test.dll /y

    Alternatively, you can reboot and then replace the DLL, so long at it is not loaded.

  10. Alternatively, you can install the DLL to a temporary file in any random directory the browser uses as the current directory. You have to install it afresh on every run. The problem is because it is a DLL, you can’t delete it until the next reboot. File.delete() and File. deleteOnExit() will fail. There is no such thing as  File.deleteOnReboot (), so I suggest using HunkIO. createTempFile which generates filenames that will be more easily recognized as junk and discarded later by some disk cleaner, or by your own program on a subsequent run.
  11. Use the Java native method as if it were an ordinary Java method.
  12. Normally, Java calls C/C++, but you can do the reverse. Normally you just pass primitives back and forth. On the C++ side, you can create a Java object with the JNI API (Application Programming Interface) and populate its fields and return it, most commonly a String. You can also create C++ objects and use them on the C++ side. They mean nothing on the Java side so you can’t bring them over into Java without converting them to Java objects first. Similarly, you can’t create arbitrary C++ objects from the Java side.

Some general JNI tips

C/C++ Primitive Types

JNI Primitive Types To Use in C/C++
Type Purpose Typedef Java/C/C++
jboolean 8-bit Boolean typedef unsigned char jboolean; C/C++
char 8-bit byte C/C++
jbyte 8-bit signed byte typedef signed char jbyte; C/C++
WORD 16-bit unsigned short, typedef unsigned short WORD; C/C++
wchar_t 16-bit unsigned char C/C++
WCHAR 16-bit unsigned char, wide char typedef wchar_t WCHAR; C/C++
TCHAR 16-bit unsigned char on Unicode supporting systems, 8-bit unsigned char or older systems, text char typedef WCHAR TCHAR; C/C++
jchar 16-bit unsigned char typedef unsigned short jchar; Java
jshort 16-bit signed short typedef short jshort; Java
DWORD 32-bit unsigned int, double word typedef unsigned long DWORD; C/C++
LPDWORD DWORD *, pointer to 32-bit unsigned int, long pointer double word typedef DWORD far * LPDWORD; C/C++
BOOL 32-bit Boolean. TRUE/true=1 FALSE/false=0, Boolean typedef int BOOL; C/C++
int 32-bit signed int C/C++
long 32-bit signed int C/C++
jint 32-bit signed int typedef long jint; Java
jfloat 32-bit signed float typedef float jfloat; Java
long long 64-bit signed long C/C++
jlong 64-bit signed long typedef __int64 jlong; Java
LPSTR char *, pointer to 8-bit null-terminated string typedef __nullterminated CHAR * LPSTR; C/C++
LPCSTR const char *, constant pointer to 8-bit null-terminated string, long pointer constant string typedef __nullterminated CONST CHAR * LPCSTR; C/C++
LPTSTR wchar_t *, pointer to 16-bit null-terminated string on Unicode-supporting platforms. On older platforms it means char *, pointer to 8-bit null-terminated string, long pointer text string typedef LPCWSTR LPCTSTR; C/C++
LPCTSTR const wchar_t *, constant pointer to 16-bit null-terminated string on Unicode-supporting platforms. On older platforms it means char *, pointer to 8-bit null-terminated string, long pointer constant text string typedef LPCWSTR LPCTSTR; C/C++
jdouble 64-bit signed double typedef double jdouble; Java
jstring counted Unicode String Java
JNIEnv the JNI environment with hooks to the JNI library methods Java
See also the table of sizeof native C++ types.

JNI Manipulator Functions

JNI gives you opaque access to the Java objects. You never touch the Java objects directly, you always manipulate them via rather clumsy remote access methods. It is bit like being a blind brain surgeon using barbecue tongs. The advantage is your program never need know what the actual format of the objects is. It makes it much easier to write portable C/C++ code.
Useful JNI functions to Access Parameters
type get parm put parm release parm return notes
Unicode String
converted to 16-bit chars
- ReleaseStringChars NewString The result of GetStringChars is not null delimited! You must copy and append your own null with wcsncpy_s.

C++ Unicode 16-bit functions do not work (quietly degrade to 8-bit mode) unless you define both:

#define UNICODE
#define _UNICODE
UTF-8 String
converted to 8-bit chars
- ReleaseStringUTFChars NewStringUTF
The result of GetStringUTFChars is automatically null delimited, though Oracle documentation is unclear. You might wonder at the asymmetry with GetStringChars. 16-bit strings need not copy. GetStringChars can us the original java 16-bit string which is not null terminated. 8-bit requires a copy, so GetStringUTFChars might as well append a null while it at it.
int use parm directly - - use local jint
copy access
SetIntArrayRegion - NewIntArray
direct access
- ReleaseIntArrayElements NewIntArray
Object use parm directly - - NewObject
copy access
SetObjectArrayRegion - NewObjectArray
direct access
- ReleaseObjectArrayElements NewObjectArray
static field in Object GetStaticFieldID
- -
instance field in Object GetFieldID
- -
callback static method FindClass
- - -
callback instance method FindClass
- - -
In the above table, wherever you see Int, you can replace it with Boolean, Byte, Char, Short, Long, Float or Double. Note these methods do not follow Java capitalisation conventions.

Typical JNI C Code

Here is some typical JNI C code to open a file, that lets you access a Java string inside C.

Typical JNI C++ Code

Here is the C++ code for accessing the volume serial number of drive under Windows: Here 

Compiling JNI C/C++ Code

Presuming your JNI class with native methods is called Mouse you will need to write a C or C++ program called mouse.cpp that contains the methods for nativemouse.dll. Your C/C+ program mouse.cpp will implement the methods in the generated mouse.h file.

Get a clean compile of your Java code, then use javah.exe like this:

If you are using Microsoft’s commercial C/C++ compiler you must have J:\Program Files\java\jdk1.8.0_112\ \include and J:\Program Files\java\jdk1.8.0_112\ \include\win32 in the include list. To configure click: Tools | options | Projects and Solutions | VC++ directories | include files or click: tools | options | directories | include.

For project as a whole, configure: project | settings | general | no MFC (Microsoft Foundation Classes) and In project | settings | link | output filename | should end in DLL

For the free MS Visual C++ Express 12, configure your project as a DLL library. Include the two JNI libraries J:\Program Files\java\jdk1.8.0_112\\include and J:\Program Files\java\jdk1.8.0_112\ \include\win32 in the /I section when you first define the project, (not forced includes) or change them later in right click | project properties| C/ C++ | additional include directories. Every time the JDK changes, you must manually change every JNI project file for both debug and release.

Turn off incremental linking. Turn off the 64-bit warnings.

In project | C++ | code generation set the runtime library /MT option to statically link (i.e. include system run time code in the DLL rather than link to the runtime. Alternatively, you must install the C++ runtime on all clients, available from:

The command line equivalents to your GUI (Graphic User Interface) options should look something like this for debug:

and  Use the batch rebuild to ensure both debug and release versions compile and link without warnings.

JNI and Assembler

To write the JNI code partly in assembler, there are two approaches: Microsoft C conventions return an int value in eax or a long in edx:eax. You can learn the register conventions by adding the /FA option to the project C++ settings and looking at the generated *.ASM code for C++ or C programs.

Here is a sample using inline Assembler. Leaving a value in eax without a ret is how you return a value, even though it generates a compiler warning message.

JNI Example Code

I have posted five programs with source that use JNI : FileTimes, Mouse, Pentium, Volser, SetClock.

Using JNI in Applets

I drove myself nuts trying to get JNI to work with signed Applets back in the days of Netscape proprietary signing and JVMs (Java Virtual Machines). I gave up and went with Java Web Start. It may be easier now. What following are notes from those terribly frustrating times.

Using native methods in a Netscape Applet is a bear because even after you manage to defang the security manager

PrivilegeManager.enablePrivilege( "UniversalLinkAccess" );
to let you call your native methods,System.loadLibrary ( mydll) and the undocumented security system, will insist that the *.DLL file containing the your native methods and all your classes be pre-installed on the client’s machine. It refuses to look for them in the jar file or on the website where CODEBASE points. You are pretty well stuck making your Applet install the necessary DLLs and class files on the client’s machine. Ouch! System. loadLibrary fails for some reason if the DLL was not present at the time Netscape fired up. The System. loadLibrary can’t seem to see a DLL installed dynamically. This makes no sense since the DLL is not loaded until System. loadLibrary is called. Even more baffling is why System. load would show the same behaviour. I have fooled around with this for months and I still could not get Netscape System. loadLibrary to behave reliably and predictably. Until that problem is solved, I consider it practically impossible to use JNI from Applets.

I got word from Hannu Helminen that it is possible after all. He came across this JavaWorld Article. What is says basically that Netscape and native code do work together after all. He tried it out and to his amazement the example indeed works! But hey, he did the same things that I did, where is the catch?

The idea is that first you download the native DLL and a class file to user’s local hard drive. The class file has to be in the Netscape class path, thus it uses the system class loader. Also the DLL has to be downloaded and System. loaded before the class is referenced for the first time. It appears that Netscape does some kind of checking for the DLLs already when the class is loaded. I have not yet had time to check this out myself.

To make it worse, there are fourteen security bypassing schemes you have to deal with.

System.load vs System.loadLibrary

System.load takes a fully qualified filename, e.g. C:\dlls\myjni.dll, one ending in *.dll (or *.so for Linux or Solaris). System. loadLibrary takes an unqualified filename, e.g. myjni and appends the .dll or .so for you. The idea is you can write more platform-independent code this way. I have had more success with  System.load during debugging then flipping to  System.loadLibrary once all is working. I suspect there is a mother of a gotcha hidden in loadLibrary not yet revealed. Check out the system property java.library.path with Wassup to see where the restricted system property System.loadLibrary is looking for DLLs. It will be the usual executable path plus a few extra directories. Alternatively find out the library 
// display where loadLibrary is looking for native code
out.println ( System.getProperty( "java.library.path" ) );
In an application or the Opera browser, you can determine the library load path with:
// Discovering the path where native code goes for an application.
// Most browsers do NOT support this, except Opera.
String lib = System.getProperty( "java.library.path" );
You must explicitly load the corresponding DLL before using any class inside it. On W98, Me, NT, W2K, XP, W2003, Vista, W2008, W7-32, W7-64, W8-32, W8-64, W2012, W10-32 and W10-64, that library path is supposed to contain: The library path depends on whether you wrote an Applet or application, which browser and the phases of the moon.

Windows loadLibrary

On W98, Me, NT, W2K, XP, W2003, Vista, W2008, W7-32, W7-64, W8-32, W8-64, W2012, W10-32 and W10-64 make sure you put your JNI shared object library *.dll somewhere on the library path. If your use  System.loadLibrary ( dog ), then you must name your library file with your compiled C++ code dog.dll. Put dog.dll directly on the library path, not in a package name sprouting off the library path. If no existing directory in the java.library.path is suitable, put the dll in some other directory and add that directory to the ordinary executable path by adding it in the control panel set environment. It will be automatically included in java.library.path. To share a your native library on a LAN (Local Area Network), assign a dummy network drive letter to the server:directory where you put it and add that to the path of each client. With JWS, you can put dog.dll in a jar, but don’t give it a package name.

Solaris and Linux loadLibrary

In Linux, to compile and link the C/C++ code, use: to tell it where to find the JNI headers. In Linux there is an environment variable called LD_LIBRARY_PATH that controls the path where *.so files are searched for. On Solaris or Linux, make sure you put your JNI shared object library *.so somewhere on the library path. If your use System. loadLibrary( dog ), then you must name your library file with your compiled C++ code libdog.so. Put libdog.so directly on the library path, not in a package name sprouting off the library path. With JWS (Java Web Start), you an put libdog.so in a jar, but don’t give it a package name.


On the Macintosh, make sure you put your JNI shared object library lib*.jnilib somewhere on the library path. If your use System. loadLibrary( dog ), then you must name your library file with your compiled C++ code libdog.jnilib. Put libdog.jnilib directly on the library path, not in a package name sprouting off the library path. With JWS, you can put libdog.jnilib in a jar, but don’t give it a package name. Apple Java has a Java-access to the proprietary Mac API, so you don’t often need JNI.

DLL in the Jar

If you want to put your DLLs in the jar, you must bundle them as resources, then to load them, read the resource from the jar and copy them to a temp file, then a System.load the temporary file. The process is somewhat more complicated that you might think.

File Naming Conventions

Naming things so that the various parts can find each other is perhaps the trickiest part of JNI. It does not matter exactly what naming convention you use, just that you be 100% consistent. Here is the scheme I use in production. I put each class with JNI into its own package.
File Naming Conventions for JNI
Filename Purpose
com/mindprod/mouse/Mouse.java The main Java class that contains some native methods.
com/mindprod/mouse/nativemouse/mouse.c The C program that implements the native methods.
com/mindprod/mouse/nativemouse/mouse.h The C header file generated by Javah giving the C prototypes for the native methods to be implemented in C
com/mindprod/mouse/nativemouse/Release/nativemouse.dll The DLL native executable library containing the native implementations. Before it can be used, it must be copied somewhere on java.library.path, the system path, or in the jar without a package name. You load the dll, using in a static init of the Mouse class, with System. loadLibrary ( nativemouse );Note the lack of .dll or path information.


C++ called via JNI knows nothing about Java exceptions. Java exceptions created in C++ are just control blocks lying about. They have no automatic effect on program flow. It is up to you in some C++ish way, after you set up the exception, to return quickly and gracefully up the call stack to your caller back in Java who can then handle the exception. On your way back, C++ can handle or notice the exception by explicitly testing for it with ExceptionCheck.


Here are basics of how to make JNI threadsafe:


JNI Methods Useful In Reflection
Method Use
GetSuperclass returns superclass of a class reference.
IsAssignableFrom checks whether instances of one class can be used when instances of another are expected.
GetObjectClass return the class of a given jobject.
IsInstanceOf checks whether a jobject is an instance of a given class.
FromReflectedField Convert a java.lang.reflect.Fieldreflect.Field to a field ID.
ToReflectedField Convert a to a field ID to a java.lang.reflect.Field.
FromReflectedMethod Convert java.lang.reflect.Methodreflect.Method or a java.lang.reflect.Constructor to a method ID.
ToReflectedMethod Convert method ID to a  java.lang.reflect.Methodreflect.Method or a java.lang.reflect.Constructor.
The equivalent JNI C code for the following fragment of Java is much more long winded:
// Java reflection
Class theClass = Class.forName( "java.lang.Long" );
Constructor constructorList[] = theClass.getConstructors();

The Old Netscape Problem

This describes a problem with earlier versions of Netscape. The new versions work quite differently. Netscape won’t let web-loaded Applets invoke DLL code, even if they have UniversalLinkAccess permission. Further, it won’t let them use a custom ClassLoader to do it indirectly. You may bypass this with the undocumented MarimbaInternalTarget class. Your custom classloader must do a  Class.getClass () first before attempting to fulfill the request itself.

The Old Netscape Solution

This applies to earlier versions of Netscape. New ones behave quite differently. You don’t need to deal with any of this security, installing and jar-signing stuff if you use an application instead of an Applet. I strongly suggest that approach wherever possible.

I have fooled around with this over a period of six months, chasing wild goose after wild goose and have finally came to the conclusion, in agreement with Oracle’s FAQ (Frequently Asked Questions), that JNI and Applets simply don’t mix. There is simply no way to get sufficient security clearance to let you directly access the DLL from a web-loaded Applet, even if you write a custom ClassLoader. One problem with doing so many tests is I could have slipped somewhere along the line, thinking I tested two cases, when I actually tested only one. The problem is the way Windows/Netscape hold onto the old code. I have not even got the method I describe below to work. It may fail too. Netscape security may apply even if you load from local hard disk.

What you have to do is use a small signed installer Applet to install a second unsigned Worker Applet on the client’s local hard disk. When that second Worker Applet runs, it is totally free of security restrictions and so can access JNI DLLs. It behaves much like an application, except it runs under a browser.

You also have to install some html in that same local directory that will load the Worker Applet from the local hard disk. It would have CODE and ARCHIVE parameters, but no CODEBASE. It defaults to the local hard disk directory where the html file lives.

You have to install the DLL in X:\Program Files\Netscape\Communicator\program\java\bin\, which is guaranteed to be on Netscape’s Windows path, where Windows looks for DLLs.

You have to install the unsigned Worker jar file in X:\Program Files\Netscape\Communicator\program\java\classes\. Netscape totally trusts classes it loads from the local file system, even if they are not signed and have no capabilities calls.

The Old Netscape Recipe

Just follow this recipe, if this discussion is making your brain hurt. The same technique will work for other platforms with the obvious substitutions. If you do understand it, you can create your own shortcuts.

In order to execute JNI methods from a Netscape Applet, create three jar files.

  1. installer.jar. When this signed jar is first executed, it installs the various files on the client’s local hard disk, (intelligently choosing C: or D:). On subsequent executions, it notices the needed files are already installed and up-to-date and avoids that step. As soon as it has ensured it has installed the files, it uses getAppletContext().showDocument(url) to transfer control to the HTML (Hypertext Markup Language) it has downloaded on C: or D: The installer jar contains only the tools such as FileTransfer classes for help in downloading and installing the files. It does not contain any of the data to be installed. Keeping that out of installer.jar saves transferring that bulk when it is already installed.
  2. Worker.jar is for your class files that contain native methods and the other classes you need to run the actual Applet. This jar should not be signed. If you sign it, it will slow class loading the code down. The Worker.jar will be embedded inside the toInstall jar, described shortly. The installer Applet will copy the Worker.jar to X:\Program Files\Netscape\Communicator\program\java\classes\ or perhaps D:. Thereafter, you could run it standalone via a bookmark, or you could run it via the original install.jar. The advantage of using the original install.jar is automatic updates and automatic finding where the Worker.jar Applet is installed. The disadvantage is extra startup time and an extra annoying grant to run the program each time.
  3. toInstall.jar. This unsigned jar is just a container for the various files you need to download namely:
    • An HTML file to invoke the actual Applet. Your installer Applet will install it in: X:\Program Files\Netscape\Communicator\program\java\classes\, or perhaps D:.
    • Your DLL file containing the native C++/C/Assembler code. Your installer Applet will install it in X:\Program Files\Netscape\Communicator\program\java\bin\, or perhaps D:.
    • Your worker Applet jar containing all the class files you will need to run the unsigned Applet. Your installer Applet will install it in X:\Program Files\Netscape\Communicator\program\java\classes\ or perhaps D:.

    If you use getResourceAsStream, you must use the goofy extension *.ram for resources inside your jar files because Netscape interferes with the extensions *.dll, *.exe, *.class etc. If you access them via ZipFile that kludge is not necessary.


The key to debugging JNI is to write a C/C++ test harness (unit test) to test your C/C++ application code. Then when it is working write the JNI glue to call your C/ C++ application methods. Let’s say, for example, you were going to write some code to get at the CPU serial number like Pentium. You write a C method to get the serial number. You write a C/ C++ mainline that calls your method and prints out the serial number on the console. You use pure C/ C++ debugging tools to get this all working. Then once you are sure your method is working, you write the JNI glue to call it from Java. The JNI is pretty mechanical after you have done it a few times. You don’t do anything fancy in the JNI code. Anything tricky you do in the C/ C++ method or in the Java code that calls the native method. JNI is ugly and so you want to keep it as simple as possible, as free of application logic as possible.

Another strategy is to write dummy JNI methods in standard Java. Introduce your real JNI code one class/method at a time and see when it starts to blow up. That localises the problem.

I see references to com.sun.jna.win32.StdCallLibrary, which looks like a way to access the Windows API, but I can’t find any documentation on it.


In Windows, 32 and 64-bit DLLs use the same extension *.dll so you must either provide two distributions, each either pure 32-bit or pure-64-bit, on provide both versions in separate directories. Or you might name your DLLs with a suffix of 32.dll, 86.dll or 64.dll. The contents of J:\Program Files (x86)\java\jdk1.8.0_112\include\ and J:\Program Files\java\jdk1.8.0_112\include\ are the same, including the Win32 directory. I gather it is purely the C++ compiler directives that decide whether to generate 32 or 64 bit code. I don’t have a 64-bit C++ compiler, so I have never tried the experiment.


You likely are saying to yourself, What a production! There must be a simpler way. Here are some alternatives:


My essay has only scratched the surface. You must have a text book if you hope for any success with JNI.
book cover recommend book⇒The Java Native Interface, Programmer’s Guide and Specificationto book home
by Sheng Liang 978-0-201-32577-5 paperback
publisher Prentice Hall
published 1999-06-20
Sun Microsystems. Does not cover Applet signing, or obvious JNI like accessing int parms, but he does explain many fine points well. A slim, indispensable, expensive book. The specification itself is bundled as part of the JDK docs. Part of the book is available free online.
Australian flag abe books anz abe books.ca Canadian flag
German flag abe books.de amazon.ca Canadian flag
German flag amazon.de Chapters Indigo Canadian flag
Spanish flag amazon.es Chapters Indigo eBooks Canadian flag
Spanish flag iberlibro.com abe books.com American flag
French flag abe books.fr amazon.com American flag
French flag amazon.fr Barnes & Noble American flag
Italian flag abe books.it Nook at Barnes & Noble American flag
Italian flag amazon.it Kobo American flag
India flag junglee.com Google play American flag
UK flag abe books.co.uk O’Reilly Safari American flag
UK flag amazon.co.uk Powells American flag
UN flag other stores
Greyed out stores probably do not have the item in stock. Try looking for it with a bookfinder.
book cover recommend book⇒Essential JNI, Java Native Interfaceto book home
by Rob Gordon [Author], Alan McClellan [Editor] 978-0-13-679895-8 paperback
publisher Prentice Hall
published 1998-03
This book is aimed more at the beginner than Liang’s book. It can’t very well teach you C and Java and JNI in one book, but it does not make quite so many assumptions about what you already know.
Australian flag abe books anz abe books.ca Canadian flag
German flag abe books.de amazon.ca Canadian flag
German flag amazon.de Chapters Indigo Canadian flag
Spanish flag amazon.es Chapters Indigo eBooks Canadian flag
Spanish flag iberlibro.com abe books.com American flag
French flag abe books.fr amazon.com American flag
French flag amazon.fr Barnes & Noble American flag
Italian flag abe books.it Nook at Barnes & Noble American flag
Italian flag amazon.it Kobo American flag
India flag junglee.com Google play American flag
UK flag abe books.co.uk O’Reilly Safari American flag
UK flag amazon.co.uk Powells American flag
UN flag other stores
Greyed out stores probably do not have the item in stock. Try looking for it with a bookfinder.

Learning More

Oracle’s Technote Guide on JNI Specification : available:

Oracle appears to have withdrawn the Beth Stearns tutorial.
cxxwrap (generates JNI code)
GlueGen: generates JNI code
Java Web Start
Jawin: hooks to Windows COM
JConfig (a JNI library)
JNative: for Java version 1.5 or later
JNI++ (generates JNI)
JRegistryKey: poke registry without JNI
method signatures
OOJNI AddIn: builds JNI
sizeof native C++ types
SWIG (generates JNI wrappers)
Swig: generates JNI wrappers for 13 languages
SWIG: JNI alternate
Winp: JNI library for controlling native Windows processes

This page is posted
on the web at:


Optional Replicator mirror
of mindprod.com
on local hard disk J:

Canadian Mind Products
Please the feedback from other visitors, or your own feedback about the site.
Contact Roedy. Please feel free to link to this page without explicit permission.

Your face IP:[]
You are visitor number