Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Integrate Java and C++ with Jace

The open source Jace toolkit helps simplify JNI programming

  • Print
  • Feedback

If you didn't know better, you might believe that Sun Microsystems had designed the JNI (Java Native Interface) API with the goal of discouraging Java developers from using it. After all, type safety is nearly nonexistent, error checking is absent, and making a single Java method call requires four or more JNI calls. In addition, you have to manage JNIEnv pointers, you can't use JNI references from multiple threads, you must choose between nine different functions for each possible operation, and retrieving exception information is difficult. I've probably left out a few other problems as well.

Many of these limitations result from JNI's binding to the C language, which itself suffers from poor support for type safety, exception-handling mechanisms, and genericity. While most of today's developers can develop in the more robust language C++, Sun couldn't leave those poor C developers out in the cold, which explains why JNI is the way it is today. Unfortunately, that leaves developers with a difficult and unwieldy API—but there is hope.

Jace is a free, open source toolkit designed to make JNI programming easy. It supports automatic generation of C++ proxy classes from Java classfiles and C++ integration of Java exceptions, arrays, packages, and objects. It manages the lifetimes and thread bindings of Java references transparently. Most importantly, it reduces development costs by allowing you to write code modules that are smaller, easier to understand, and compile-time type safe.

Warning: This article is not for the JNI uninitiated. I make references to JNI's nitty-gritty details, from function calls like NewGlobalRef() and GetFieldID() to the nuances of JNI thread and exception safety. If you're new to JNI, I strongly suggest you check out The Java Tutorial, the JNI specification, and JavaWorld's JNI resources (see Resources for links).

The JNI type system

Jace's fundamental strength is its use of C++ proxy classes to represent Java types. To truly understand the benefit of proxy classes, you first need to review the JNI type system. Sun uses 24 C types in JNI to represent the entire set of possible Java types. JNI has nine primitive types:

  • jboolean
  • jbyte
  • jchar
  • jshort
  • jint
  • jlong
  • jdouble
  • jfloat
  • void


JNI has 14 reference types, as Figure 1 illustrates.

Figure 1. The 14 JNI reference types (Source: Sun Microsystems)

And, finally, JNI has the composite type jvalue, which represents the entire set of primitive and reference types.

The Jace type system

Figure 2 shows a class diagram representing the basic set of Jace types. These classes are your primary interface into the Jace runtime. Not surprising, Jace classes correspond closely with JNI types.

Figure 2. The Jace object model. Click on thumbnail to view full-size image.

The Jace type system is built directly on the 24 JNI types. For every JNI type, Jace has a matching C++ proxy class. The nine JNI primitive types, along with jvalue, jclass, jobject, jstring, and jthrowable, all map directly to corresponding Jace proxy classes. The JNI type jarray and its nine derivative array types all collapse down to one template-based JArray type. In the following sections, I examine each of these C++ proxy classes in detail.

  • Print
  • Feedback

Resources