Jump to content

Java AWT Native Interface

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Dan FX (talk | contribs) at 00:49, 5 August 2023 (Added more info and removed the "how-to"). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

The definition of Java Standard Edition includes JNI, the Java Native Interface. Most Java developers will never need to use it, but the interface is invaluable in certain situations because it provides the only way for Java byte code to interact directly with application code that has been compiled to the native machine instructions for the host microprocessor. JNI is most often used as an ``escape valve'' to enable access to platform functionality not yet supported by the Java programming language. For example, you could use JNI to integrate with native code that communicates with a peripheral device, such as a scanner, connected to a system via a USB port.

Of course, JNI is general enough to be used to access almost any sort of native library, regardless of whether the task to be accomplished could also be done using pure Java. The major penalty for using it is that code portability suffers, but this may be acceptable or even necessary for business or technical reasons.

Business reasons? Consider the situation where the legacy software you are trying to port to Java uses a third-party library for a critical set of operations. If you do not have source rights to this library and you cannot convince the owner to provide a Java version, you may not be able to use it. Even if you do have the source, the effort needed to port a standard library to Java and test it may be too expensive to consider.

Another important reason for leaving the native code alone is related to performance. If you are dealing with a finely crafted piece of code, carefully tuned for performance over the course of years, you probably do not want to convert it to Java and risk a performance penalty. It is usually best to keep it intact until you are satisfied that the benefits of Java portability and code maintainability outweigh the expected performance difference.

A rendering library is a good example of a piece of native code that most developers would just as soon leave alone for performance reasons. Unfortunately, this is the very type of library that has been most difficult to integrate with Java code through JNI. The fundamental problem has been that the rendering code cannot identify where to draw. It needs access to information about a Java drawing surface (such as a handle to the underlying peer of a Canvas), but cannot get it.

Until now, the Java platform has kept access to this information private — "private" in the sense of undocumented, unsupported, and deprecated. The good news is that this situation will be remedied with the introduction of the "AWT Native Interface" in the Java upgrade release ("Kestrel"). For the first time there will be an official way to obtain all the information you need to know about the peer of a Java Canvas so that you can draw directly to the Canvas from a native code library using the drawing routines provided by the operating system.

Native painting

One can paint as if it is a native application. In Windows, the JVM will pass a HWND and other window information to the native application so that the application will "know" where to draw. It could use GDI to draw a Rectangle. The window information the native side needs will be in a JAWT_Win32DrawingSurfaceInfo structure (depending on Operating System) which can be retrieved with this line: dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;