By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,118 Members | 1,133 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,118 IT Pros & Developers. It's quick & easy.

JNI and Java Threads

P: n/a
Rob
Hi there,

Firstly, apologies for x-post but I'm hoping the post is relevant to both
groups...

I have written a native implementation in C, and a java wrapper class. This
all works fine and correctly while I am calling the wrapper methods from a
single thread, however, my application requires calling the wrapper methods
for the native code from several different (java) threads.

And this is where I get stuck! - I am getting garbage values back from
native unless I use the same thread each time.

I have implemented something whereby I start a new thread, and then
wait/notify as each of the other requesting threads contact this single
thread, and then that single threads toodles off to native, but that causes
problems with waiting for return values and also makes the code far more
complicated that I believe it should be.

I have seen mentions of the functions 'JNI_GetCreatedJavaVMs' and
'AttachCurrentThread()', but as far as I can see, these are mainly for
contacting the JVM from the C and not the other way around. (I may well be
(and hope I am!) wrong).

This is a passage from a book I have which seems to answer my question,
kinda:

"Since a native method may be called from different threads in a Java
application, each different invocation of that native method will have a
different JNIEnv pointer passed to it. Passing this information to another
thread will result in unpredictable behaviour.
On the other hand, for a given method, from a given thread, the JVM
guarantees that the same JNIEnv pointer is passed on each call to that
method."

This seems to say that what I want is not possible, but regardless its what
I need lol so one way or another I need to figure it out. (I'm calling
native methods from the GUI and from event register calls etc.) Can anyone
offer any relatively clean work arounds or suggestions to how this can be
done? (other than the messy way I've tested as suggested above?)

Thanks for any anyone can offer, I've been on this for days!!! I'm hoping
I've been way off base and that the answer is simple.... but hey, I also
understand that this is computing...

Rob.
Jul 17 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Rob wrote:
And this is where I get stuck! - I am getting garbage values back from
native unless I use the same thread each time.
[SNIP]
This seems to say that what I want is not possible, but regardless its what
I need lol so one way or another I need to figure it out. (I'm calling
native methods from the GUI and from event register calls etc.) Can anyone
offer any relatively clean work arounds or suggestions to how this can be
done? (other than the messy way I've tested as suggested above?)

Ok. Well you've told us a little on *how* you think you need to do what
you want to do, but not *what* you need to do.

Tell us *what* you want, then we can help more.
Without further details, I'd guess that you're passing around and
holding transient pointers when you shouldn't. By going to a single
thread, you hide this problem by not triggering the symptom, but it
probably is still there. I'd wager that you have some broken code on the
C side that needs cleaning up.

Jul 17 '05 #2

P: n/a
Rob
"Jon A. Cruz" <jo*@joncruz.org> wrote in message
news:40**************@joncruz.org...

Ok. Well you've told us a little on *how* you think you need to do what
you want to do, but not *what* you need to do.

Tell us *what* you want, then we can help more.
Without further details, I'd guess that you're passing around and
holding transient pointers when you shouldn't. By going to a single
thread, you hide this problem by not triggering the symptom, but it
probably is still there. I'd wager that you have some broken code on the
C side that needs cleaning up.


Hmmm, well, the application is to control an audio cd. The native side has
various methods (open, play, getCurrentTime, stop etc.), and the java side
has a wrapper class which holds the device handle for the cd drive. So when
I call the native 'open', a device handle (int) is returned to the java
which I then use as an argument to call the native methods play, stop etc.

So from the GUI, I am pressing the 'open' then the 'play' button, but from
another thread I am polling the wrapper classes 'getCurrentTime' and other
methods to continually update a textual display of the cd status. And in
future I'll probably be wanting to add more thready methods for more
advanced status features.

If I add a 'button' to the GUI, which calls the 'getCurrentTime' method, it
works fine... however, if I press the 'open' button on the GUI, and then
rely on a separate thread to poll native and update the time/clock display
on the cd player, I get garbage values back...

I'm not entirely sure which info is needed, but is this any help as to what
I am doing wrong?

Thanks,
Rob.

Jul 17 '05 #3

P: n/a
Rob...

I've found JNI to be very buggy when called from seperate threads.....

....So make sure only one thread ever calls your native code!

Make your wrapper methods, such as playCD() notify a seperate thread which
in turn calls the native code.
Something like this:

int methodToCall;
final int PLAY = 1;

//run as seperate thread using thread.start()
public synchronized void run()
{
while( true )
{
wait();
switch( methodToCall )
{
case PLAY:
JNI_PlayCD(JNIEnv env, ...)
break;
.....
}
}
}

public synchronized void playCD()
{
methodToCall = PLAY;
notifyAll();
}
"Rob" <.@.com> wrote in message
news:40**********************@news.dial.pipex.com. ..
Hi there,

Firstly, apologies for x-post but I'm hoping the post is relevant to both
groups...

I have written a native implementation in C, and a java wrapper class. This all works fine and correctly while I am calling the wrapper methods from a
single thread, however, my application requires calling the wrapper methods for the native code from several different (java) threads.

And this is where I get stuck! - I am getting garbage values back from
native unless I use the same thread each time.

I have implemented something whereby I start a new thread, and then
wait/notify as each of the other requesting threads contact this single
thread, and then that single threads toodles off to native, but that causes problems with waiting for return values and also makes the code far more
complicated that I believe it should be.

I have seen mentions of the functions 'JNI_GetCreatedJavaVMs' and
'AttachCurrentThread()', but as far as I can see, these are mainly for
contacting the JVM from the C and not the other way around. (I may well be (and hope I am!) wrong).

This is a passage from a book I have which seems to answer my question,
kinda:

"Since a native method may be called from different threads in a Java
application, each different invocation of that native method will have a
different JNIEnv pointer passed to it. Passing this information to another thread will result in unpredictable behaviour.
On the other hand, for a given method, from a given thread, the JVM
guarantees that the same JNIEnv pointer is passed on each call to that
method."

This seems to say that what I want is not possible, but regardless its what I need lol so one way or another I need to figure it out. (I'm calling
native methods from the GUI and from event register calls etc.) Can anyone offer any relatively clean work arounds or suggestions to how this can be
done? (other than the messy way I've tested as suggested above?)

Thanks for any anyone can offer, I've been on this for days!!! I'm hoping
I've been way off base and that the answer is simple.... but hey, I also
understand that this is computing...

Rob.

Jul 17 '05 #4

P: n/a
nos

"Rob" <.@.com> wrote in message
news:40**********************@news.dial.pipex.com. ..
Hi there,

Firstly, apologies for x-post but I'm hoping the post is relevant to both
groups...

I have written a native implementation in C, and a java wrapper class. This all works fine and correctly while I am calling the wrapper methods from a
single thread, however, my application requires calling the wrapper methods for the native code from several different (java) threads.

And this is where I get stuck! - I am getting garbage values back from
native unless I use the same thread each time.

I have implemented something whereby I start a new thread, and then
wait/notify as each of the other requesting threads contact this single
thread, and then that single threads toodles off to native, but that causes problems with waiting for return values and also makes the code far more
complicated that I believe it should be.

I have seen mentions of the functions 'JNI_GetCreatedJavaVMs' and
'AttachCurrentThread()', but as far as I can see, these are mainly for
contacting the JVM from the C and not the other way around. (I may well be (and hope I am!) wrong).

This is a passage from a book I have which seems to answer my question,
kinda:

"Since a native method may be called from different threads in a Java
application, each different invocation of that native method will have a
different JNIEnv pointer passed to it. Passing this information to another thread will result in unpredictable behaviour.
On the other hand, for a given method, from a given thread, the JVM
guarantees that the same JNIEnv pointer is passed on each call to that
method."

This seems to say that what I want is not possible, but regardless its what I need lol so one way or another I need to figure it out. (I'm calling
native methods from the GUI and from event register calls etc.) Can anyone offer any relatively clean work arounds or suggestions to how this can be
done? (other than the messy way I've tested as suggested above?)

Thanks for any anyone can offer, I've been on this for days!!! I'm hoping
I've been way off base and that the answer is simple.... but hey, I also
understand that this is computing...

Rob.

Does the 'c' program have to be re-entrant?
Jul 17 '05 #5

P: n/a
[unofficial newsgroup trimmed]

Rob wrote:

So from the GUI, I am pressing the 'open' then the 'play' button, but from
another thread I am polling the wrapper classes 'getCurrentTime' and other
methods to continually update a textual display of the cd status. And in
future I'll probably be wanting to add more thready methods for more
advanced status features.
Hmmm.. that there sounds fairly poor as far as design goes. Instead of
polling, you should register listeners and have the native code generate
notifications. In general, polling should be avoided when possible.


If I add a 'button' to the GUI, which calls the 'getCurrentTime' method, it
works fine... however, if I press the 'open' button on the GUI, and then
rely on a separate thread to poll native and update the time/clock display
on the cd player, I get garbage values back...


Hmmm... what kind of 'garbage', and what should you get? Have you added
debug output to your native code to see what it's getting and doing?

Are you storing anything in the JNI side of things? Are you keeping any
object references, jenv pointers or anything else?

Jul 17 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.