Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / July 2005

Tip: Looking for answers? Try searching our database.

Transfering callback function to jni

Thread view: 
John Smith - 26 Jul 2005 19:54 GMT
Hi everyone,

Lets say you have a jni function which accepts a callback function.
This function should be set from within java and called if a failure happens
in the jni code.

The only examples I've seen of java callbacks are where the java function is
already known and hardcoded in the jni code. However assume you have a java
class which calls this jni function you want to be able to create multiple
objects of this class pointing to each their different function.

In other words how can I make a java function into a jni function pointer
and transfer it to the jni code. In .NET this is quite easy by using
delegates.

Is it possible in java too or do you need to hardcode the function name
inside jni?

Thanks in advance.

-- John
jan V - 26 Jul 2005 20:06 GMT
> In other words how can I make a java function into a jni function pointer
> and transfer it to the jni code. In .NET this is quite easy by using
> delegates.
>
> Is it possible in java too or do you need to hardcode the function name
> inside jni?

If you take a few steps back, maybe you'll agree that you're trying to solve
a messy architectural problem. Instead of finding a solution for your stated
problem, maybe you should re-architect the Java-JNI-C interface so that
you/it obey the KISS principle. E.g. break the C code into more primitive
chunks which are not given the responsibility to call Java when an error
occurs, but simply include a C routine which tells you whether an error
occurred or not.

But before you consider this route, are you 500% sure you need JNI at all?
John Smith - 26 Jul 2005 21:54 GMT
> If you take a few steps back, maybe you'll agree that you're trying to solve
> a messy architectural problem. Instead of finding a solution for your stated
[quoted text clipped - 5 lines]
>
> But before you consider this route, are you 500% sure you need JNI at all?

Yes I am sure I need JNI.
Thing is that I have a library already written in C and I want to expose
this library through a java wrapper. Building functions which signals errors
is one way to solve it but it's not very efficient though. The calling java
application needs to poll for the error to happen.
I don't like the idea of methods which are hardcoded into jni as callbacks.
This is just messy if you have more java objects of the wrapper class and
forces it to become a singleton class.

I understand that looking from a strict java perspective it's not very
efficient. However in my case it's a matter of java support to my
application or none at all. Rewriting thousands of lines from C++ into java
is not an option.

Thanks in advance.

-- John
Chris Uppal - 27 Jul 2005 08:08 GMT
> Is it possible in java too or do you need to hardcode the function name
> inside jni?

You either have to hard-code the function name in the JNI code, or tell the JNI
code somehow what the name of the function is.  Overall the former is simpler
;-)

If it bothers you, you can set up a helper class like:

  abstract class Callback
   {
       abstract void doIt();
   }

And then pass instances of nested and/or inner classes to JNI, e.g:

   class Example
   {
       private void
       theRealHandler(String location)
       {
           // just for example
           System.err.println("Error in Example." + location + "()");
       }

       void
       methodThatUsesJNI()
       {
           Callback callback = new Callback()
                                         {
                                               void doIt()
                                               {

theRealHander("methodThatUsesJNI");
                                               }
                                         };
           callJNI(params, callback);
       }
   }

If you see what I mean (and if I haven't cocked up the bloody obfuscatory
anonymous class syntax again).

The idea is that you define the Callback class once, and use "local" subclasses
of it everywhere.  JNI only needs to know about (and hard-code) the one
Callback method.

   -- chris
A_Wieminer - 27 Jul 2005 09:48 GMT
>>Is it possible in java too or do you need to hardcode the function name
>>inside jni?

> You either have to hard-code the function name in the JNI code, or tell the JNI
> code somehow what the name of the function is.  Overall the former is simpler
[quoted text clipped - 39 lines]
> of it everywhere.  JNI only needs to know about (and hard-code) the one
> Callback method.

Nice and simple abstract callback layer. However, I have always wondered
whether its safe to call java method from _any_ native thread. Virtual
machine does not bother the origin thread it is just us to maintain a
thread safety code when doing callbacks from native side?
Chris Uppal - 27 Jul 2005 11:17 GMT
> However, I have always wondered
> whether its safe to call java method from _any_ native thread. Virtual
> machine does not bother the origin thread it is just us to maintain a
> thread safety code when doing callbacks from native side?

I'm not sure that I have understood your question properly. If the following
doesn't answer your question then please ask again.

There are two parts to this.

The first part is that there are definite rules about which threads are allowed
to call back from native code into Java.  If thread is executing native code
because that code has been called from Java, then it's OK for it to call back
into Java (on the same thread).  If a thread is the one that originally created
the JVM, then it can call into Java whenever it wants.  Otherwise, as I
understand it (I've never had to use this so I may be wrong), a thread can only
call Java code if it has registered itself with the JVM by using the JNI
AttachCurrentThread() function (or similar).  Basically you can only call Java
code from native threads that the JVM "knows" about.  A related problem for JNI
programmers, is that the references to Java objects that Java provides when it
invokes JNI code, are only valid on that thread.  If the programmer wants to
store a reference to the object for use on another thread, then s/he has to
convert the reference to a so-called "global" reference (and remember to
release it later).  So, for instance, the Callback object in my example
couldn't just be stored or passed from thread to thread in the OP's JNI code --
if he wanted to do that, then he'd have to code for it specially, following the
JNI rules.

The second part is that -- providing the above rules are followed -- the
callback can be invoked from any thread.  In this case the picture is just the
same as if the callback had been invoked from Java code running in a different
(or potentially different) Java Thread.  If that possibility is allowed by your
application design (it may not be), then you have to code for it by using
synchronized methods and blocks in the usual way.  (It is also possible to
acquire/release the locks associated with any object directly from JNI, but I'd
think that would usually be a very bad idea -- and a lot of extra effort too.)

   -- chris


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.