I concur, in general, about the cryptic errors that occur with JNI coding. I tend not
to put
everything within a single function call, but I do follow the KISS principle (Keep It
Simple,
Stupid).
May I also suggest the book, "essential JNI: Java Native Interface" (sic on
capitalization), by
Rob Gordon. This is an excellent (no, authoritative) book on the subject of JNI. It
is very
well written. Following the KISS principle, you'll probably only need to read the
first 2 or 3
chapters.
There are other native interfaces available, as well. Netscape's JVM has their own
native
interface, developed before JNI was available. However, Netscape has deprecated this
interface
in favor of JNI.
Microsoft's JVM uses something called RNI (Runtime Native Interface), and does *not*
support JNI
(you can, however, use Sun's Java Plug-In, which encapsulates Sun's JVM inside an
Active-X
control). Microsoft will likely never support JNI. This is, in fact, the source of
Sun's
accusations against Microsoft for not supplying a JVM that is compliant with the Java
standard.
Why does Microsoft do this? WFC, Microsoft's Java interface to MFC, makes extensive
use of
native calls (as you might expect). In order to make WFC faster than it would
otherwise be, RNI
allows native code to get the address of Java variables directly (which, of course,
would not
work if data is moved in memory, as the JNI specification allows). To support JNI,
Microsoft
would have to cripple (in terms of speed, anyway) the WFC, something Microsoft is not
likely to
do.
We have built a bridge between RNI and JNI for our internal use (we provide Java
toolkits for
data visualization). This way, our native code and our Java code remains intact. Our
bridge
maps the RNI stubs to call the JNI stubs, and provides the JNI data access functions
in the
event that the JNI is not available. However, we do not offer this as a product
(yet). If
there is sufficient interest, we could probably be coaxed into developing this into an
actual
product. Please e-mail me if you require this functionality.
I hope this helps. Native interfaces have been the source of a lot of headaches for
Java
developers. I repeat my earlier advice: KISS.
-dan
[EMAIL PROTECTED]
Diego Pons wrote:
>
> I'll try to be less terse this time.
> First, RMI is a great solution, much simpler to code than say RPC's
> for developing client/server interfaces. The only complication is that
> to support legacy systems not written in Java, you will need to create
> a (non-portable) bridge using JNI (see Dan Kirkpatrick's response to you).
>
> JNI allows you to interface with the C language, having thus access to
> the underlying operating system or application interfaces in C.
> As D.K. says, in JNI you have to map Java classes to C structures on
> the output arguments, and C to Java on the input arguments, all the while
> checking for errors at each step. This is a lot easier to say than to do.
> Most errors will cause the JVM to dump a (most enigmatic) core.
>
> Given this difficulty, I suggest to minimize the number of JNI functions.
> One way is to create a mega-call in JNI where the parameters are a command
> and a related argument list as strings, in a way similar to ioctl() calls.
> A typical API would then be handled in this way:
>
> my_jni_call(..., OPEN_CMD, arg, NULL)
> my_jni_call(..., READ_CMD, arg, argsz)
> my_jni_call(..., WRITE_CMD, arg, argsz)
> etc, etc.
>
> While this goes against elegancy in design, it will add to the robustness
> of the product by eliminating error-prone Java<->C mapping code.
> Unfortunately, this came to me only after writing about 3000 lines of
> the interface code.
>
> I suggest reading "Core Java, Volume II", by Horstmann and Cornell for
> both RMI and JNI examples and references.
>
> --
> Diego Pons Pharos Consulting LLC