Saturday, February 5, 2011

GWT and SmartGWT - JNI and Unsatisfied Link Error

GWT uses the Java JNI mechanism in a really unique way.  JNI was originally intended to work with native code on the computer where you had your JDK, like C++.  I've had limited exposure to the JNI interface - I've only had to use it for a serial communication component.  Even then, I was using a library that relied on JNI, so I didn't generate the code, I just had to make sure the native library was on my classpath.

The Google Engineers applied this mechanism to Javascript, however.  If you want to write 'Native' Javascript in your GWT classes, its easy.  Just flag your method as native and put your javascript code, in comments, before your terminator.  Here's a sample from the Google Web site.


public static native void alert(String msg) /*-{
  $wnd.alert(msg);
}-*/;


Viola!  Instant native interface for your JavaScript CLIENT code.  That's right, just try running this method on the server.  While working on my current project, I ran into this issue accidently while trying to use a SmartGWT class.  I got a JNI error on the server because the VM couldn't find the native code.  Of course, there isn't any native code on the server.  In this case, the 'native' code is JavaScript.

I was trying to pass a SmartGWT ListGridRecord to the server so I could map it to a persistent bean.  Of course, once I saw the error, I followed the inheritance hierarchy for ListGridRecord all the way up the chain, and what did I find at the top?  JsObject.  Of course, I didn't even have to go that far.  After looking at the Record code, it relies on static methods in JSOHelper, which uses a lot of native JavaScript

In the end I had make transfer objects to use to send the data over GWT RPC. This was a good reminder, though, that while GWT looks like Java, what's being executed really isn't.