I am basically a web application developer, never in my career got a chance of trying out this.. can someone explain the whys and the wherefores for using native code in java?
- You may have a non-Java library that for whatever reasons you have to use in your Java project
- You may need to integrate some old or rarely used hardware and need to implement the interface which may be much easier in C/C++
If you want to solve a performance issue with native code than there's a 99.5% chance that this is the wrong approach ;-)
Java is platform-independent, which means that the programs you write in Java can run on any operating system - you don't even need to recompile, the compiled class files should run on any operating system.
Sometimes, however, you need to do something in your program that's very specific to a certain operating system, and there might not be a pure Java way to do what you need to do; or you might need to call an existing non-Java library. The Java platform provides JNI (Java Native Interface) as a way to call operating system specific code.
You should use native code sparingly, however, because it ties your program to a specific operating system.
Here are some quotes from Effective Java 2nd Edition, Item 54: Use native methods judiciously:
Historically, native methods have had three main uses. They provide access to platform-specific facilities such as registries and file locks. They provided access to libraries of legacy code, which could in turn provide access to legacy data. Finally, native methods were used to write performance-critical parts of applciations in native languages for improved performance.
It is legitimate to use native methods to access platform-specific facilities, but as the Java platform matures, it provides mroe and more features previously found only in host platforms. [...] It is rarely advisable to use native methods for improved performance [...]
The use of native methods has serious disadvantages. Because native languages are not safe, applications using native methods are no longer immune to memory corruption errors. Because native languages are platform dependent, applications using native methods are far less portable. Applications using native code are difficult do debug. There is a fixed cost associated with going into and out of native code, so native methods can decrease performance if they do only a small amount of work. Finally, native methods require "glue code" that is difficult to read and tedious to write.
The entire item has more detailed explanations on the issues. Along with the entire book, it is highly recommended.
See also
As a web developer you are more likely to come across native
if you use Google Web Toolkit. With that framework you essentially write Java code which is then compiled to Javascript that can run in a browser. In GWT, the native
keyword is used to make calls to "native" Javascript code.
The term to look for is JSNI.
- performance
- tighter integration with native environment
- need to use native library with unique features
examples: JAI (image processing), Java 3D (OpenGL), JDIC (desktop integration)
In my experience, the downsides of using native code libraries are significant:
JNI / JNA have a tendency to destabilize the JVM, especially if you try to do something complicated. If your native code gets native code memory management wrong, there's a chance that you will crash the JVM. If your native code is non-reentrant and gets called from more than one Java thread, bad things will happen ... sporadically. And so on.
Java with native code is harder to debug than pure Java or pure C/C++.
Native code can introduce significant platform dependencies / issues for an otherwise platform independent Java app.
Native code requires a separate build framework, and that may have platform / portability issues as well.
Generally speaking, you don't gain much (if any) extra performance by using native code. While you might think your C/C++ will be more performant than Java, the JIT compiler does a pretty good job of optimizing these days, and you have to consider the performance costs of making JNI calls and other interactions across the JNI boundary.
Generally specking, you should treat JNI / JNA as a "last resort" option. If there is any other way of solving the problem, that way is probably better.