I'd go for some form of IPC (pipes, maybe even sockets). This way, your
code is reduced to copying to and from byte arrays in C++, and using
InputStreams and OutputStreams in Java.
I've recently worked on a project where we had a library distributed by
a third party, which was written in C++. But every system we have that
might use this library was written in Java.
We went down the route of wrapping the library as a native executable,
that reads input from stdin, translating it to function calls to the
library. Correspondingly, results from the library were converted and
printed to stdout.
This also meant that the wrapper was easy to test, since all I had to do
was invoke it on the command line. Spotted a lot of bugs and problems
because of this. Thoroughly recommend it.
The next problem was 'How do I invoke the C++ wrapper' and 'How do I
package it with the Java app'? We actually avoided the answers to these
questions, by exposing the executable via inetd. So our java
applications invoked the C code by opening a socket. Because I'd coded
the wrapper to communicate via stdout and stdin, I didn't have to modify
it at all to expose it via TCP (Read up on inetd if you're puzzled).
The neatest little bit of programming I've ever done... :-)
Sorry I went off on a tangent up there. I was trying to illustrate the
flexibility you can get if you decide to separate the C++ code into a
separate process. The point is, you've done the work of marshalling
your data structures up front. So initially, you might keep your other
process local and communicate to it via a pipe. The thing is, if you
ever decide that you need to send the requests to a remote TCP server,
it wouldn't take a lot of effort to change the java program. You've
already done the bulk of the work. It may be worth considering.
Whether it's actually suitable for you, I don't know.
I haven't coded with JNI, but we do have apps that use it at work, and
they all suffer memory management issues:
1) If the C/C++ code makes a mistake with pointer arithmetic, your Java
app's screwed as well. It'll probably die with a SIGSEGV. So your
C/C++ code better be solid, well tested and worth your trust. With the
project I was working on, most of the Java apps were server processes,
that are supposed to work 24/7. We didn't trust this third party
library that much, useful as it may be.
2) Passing data structures between the Java and C++ can be troublesome.
Especially if you pass Java objects into the C functions. You usually
have to perform some sort of conversion, which raises such issues like
'should I copy this data structure? When should I destroy it?' It's
especially bad if you inadvertently call 'free' on some object that was
allocated in the Java program.
3) I've seen some JNI code. It just looks ugly... [barf]
Sorry for the long post.