 | Level: Introductory Mark Bluemel, Software engineer, IBM
06 Jun 2002 JNI provides a solution to Java developers who need to run programs natively, but you should be aware of the pitfalls of the API. In this tip, Marc Bluemel shows some instances where JNI breaks down and offers some advice for when you absolutely need to use it.
There have been a number of articles, on the developerWorks Java technology zone and elsewhere, on how to write JNI code. JNI has its place, but there are also reasons not to use it:
-
You are depriving yourself of a safety net. The JVM provides a wide range of guarantees ensuring that your Java code cannot cause it to crash, corrupt data, and so on. As soon as you introduce your own native code into the equation, those guarantees are removed.
-
You are giving your JVM supplier's support personnel an escape clause. If the JVM crashes with only your 100 percent pure Java code running, it's clearly the support organization's problem; if a support person sees that your native libraries are loaded, he'll likely ask you to remove them so he has a clean JVM to work with -- and he'll have a valid point.
These are not hypothetical issues. In the last two years, I've seen crashes caused by various sorts of JNI code: type 2 (native mode) JDBC drivers from two database suppliers, native socket code from an application server package, and on and on. If you really must use JNI code, write your code strictly to the JNI specification. Do not assume that just because your code works on one platform, it will work on all of them -- the internals of JVMs differ and you may get away with nonconforming code on one platform but not on another. I recently encountered an example of this sort of problem. Depending on the implementation of your JVM, the JNI call GetIntArrayElements() and related Get<type>ArrayElements() calls return either a pointer to the Java array itself, or a pointer to a copy of it. The call also returns a flag to indicate whether the array (or other type) is a copy or not. The result is guaranteed until Release<type>ArrayElements() is called. You might think that if you are working with a pointer to the array and not a copy, you don't need to make the release call; I've seen programmers make just that assumption. However, in order to allow you to work with the array, the JVM needs to "pin" the array object in the Java heap, or the Garbage Collector might move it around. Hence, you must always use the release method, or your Java heap will fill up with pinned arrays that can't be garbage collected, and you will have a memory leak. In summary, if you are writing JNI code, always follow the specification! And if you are using Get<type>ArrayElement() calls, always use the equivalent Release call.
About the author  | |  | Mark Bluemel is a Software Engineer at IBM. |
Rate this page
|  |