Microsoft SDK for Java

Comparison of J/Direct, RNI, and Java/COM

To understand the uses and benefits of Microsoft® J/Direct™, compare it to the two other major ways of integrating Java and native code, Raw Native Interface and Java/COM integration.

RNI

With the Raw Native Interface (RNI), you have to remember to lock pointers, turn garbage collection on and off, and so on. Dynamic-link libraries (DLLs) you call through RNI need to be specially written to work with RNI. You can't use RNI to call arbitrary DLLs, although you can write wrapper DLLs.

In exchange for this complexity, you get fast performance and full access to all the fields in every object. But RNI is more complex than most programmers need, so it's better reserved for systems-level programming tasks such as extending the capabilities of the Microsoft VM.

Java/COM Integration

The Microsoft VM adds the ability to treat COM objects as special Java classes. Java/COM integration allows any JavaBean to be a Microsoft® ActiveX® Control and any ActiveX Control to be a JavaBean—all nearly automatically. Java/COM integration is best for calling APIs that are wrapped in COM objects or for ActiveX Controls.

A disadvantage to Java/COM integration is that there's a translation layer between Java and COM: the performance won't be as fast as if you were using C++ (and therefore had one less translation layer). This integration is very powerful, but if you just want to call into a C DLL (such as the Microsoft® Windows® API), you'd still have to write a wrapper COM object just to call your DLL.

J/Direct

With J/Direct, the Windows APIs are accessed with DLL calls, not by means of COM. Although RNI also provides access to DLLs, the RNI technology assumes that you started with a Java class, generated a C header file using Msjavah.exe, and then added functionality to the C DLL. But Win32 DLLs aren't callable by RNI in this way. Because Win32 API names don't conform to RNI naming conventions and because RNI expects data types (like strings) to be Java-format types (the Win32 API uses C-format types), RNI cannot be used to access Win32 or third-party DLLs. In other words, a single API cannot follow both the RNI conventions and the Windows conventions required by existing Windows-based applications.

The VM takes care of issues such as mapping of data types for you. J/Direct is best for calling APIs (in Windows or your own DLLs) that are not wrapped in COM objects. This allows you to access almost the entire Windows API, for instance—and enables a new class of Java programs: Microsoft® Windows® programs written in Java.

J/Direct is simpler to use than RNI, which requires you to write a specialized wrapper DLL and perform all non-trivial data type translations yourself. It is also faster than Java/COM integration. With J/Direct, the majority of pre-existing DLL functions can be invoked simply by declaring the function and calling it. J/Direct uses the @dll.import directive, which is similar in usage to the Microsoft® Visual Basic® DECLARE facility.

J/Direct links Java with existing code such as the Win32 API functions, which were not designed to deal with the Java garbage collector and the other subtleties of the virtual machine environment. However, J/Direct automatically calls GCEnable on your behalf so that you can call functions that block or perform UI without having a detrimental effect on the garbage collector. J/Direct also automatically translates common data types such as strings and structures to the forms expected by C functions.

The tradeoff is that DLL functions cannot access fields and methods of arbitrary Java objects. They can only access fields and methods of objects that are declared using the @dll.struct directive. Another limitation of J/Direct is that RNI functions cannot be invoked from DLL functions that have been called using J/Direct. The reason for this restriction is that garbage collection can run concurrently with your DLL functions. Therefore, any object handles returned by RNI functions or manipulated by DLL functions are inherently unstable.

Summary

J/Direct and RNI are complementary technologies. Using RNI requires that DLL functions adhere to a strict naming convention, and it requires that the DLL functions work harmoniously with the Java garbage collector. That is, RNI functions must be sure to call GCEnable and GCDisable around code that is time-consuming, code that could yield, code that could block on another thread, and code that blocks while waiting for user input. RNI functions must be specially designed to operate in the Java environment. In return, RNI functions benefit from fast access to Java object internals and the Java class loader.

Fortunately, you can use either RNI or J/Direct (or both). The compiler and the Microsoft VM allow you to mix and match J/Direct and RNI within the same class as your needs dictate.

© 1999 Microsoft Corporation. All rights reserved. Terms of use.