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 / October 2006

Tip: Looking for answers? Try searching our database.

JNI problem: Calling java from C++ dll

Thread view: 
kowald@molgen.mpg.de - 10 Oct 2006 17:00 GMT
Hello everybody,

I try to call java methods from a C++ dll usin JNI and have some
problems I don't understand.
This is under XP using Java 1.5.06

If  a function "x" of the dll is called I want to create the JVM and
get a reference to the class I intend to use:

       jint res = JNI_CreateJavaVM(&jvm,(void**)&env,&vmArgs);
       jclass jclassTmp = env->FindClass("myClass");
       jSimuClass = (jclass)(env->NewGlobalRef(jclassTmp));

I want to use the JVM and class later when a different function inside
the dll is called. Therefore I created a global reference for my class
and use global variables for env and jvm in my dll

JNIEnv          *env;
JavaVM          *jvm;
jclass          jSimuClass;

If now the function "y" of the dll is called, I try to get a method ID
doing:

           methodID = env->GetMethodID(jSimuClass, "method1", "(I)V");

AND THIS CRASHES THE C++ PROGRAM  right at this line of code (it does
not return from this call). If I place this line of code in the dll
function x, right after the creation of jSimuClass it works. If I try
in function y other JNI methods like

jclass jclassTmp = env->FindClass("myClass");

this also works, so env is still valid. The question is why is
jSimuClass no longer valid?

If the C++ part is not a dll, but a normal executable it also works. I
can create the JVM in a function call and then call GetMethodID in a
different function call. I'm now a bit clueless and any hint what could
be wrong or what is special about a dll is welcomed.

   Axel
Bill Medland - 10 Oct 2006 20:41 GMT
> Hello everybody,
>
[quoted text clipped - 38 lines]
>
>     Axel
Could it be a problem with threading?  Is it possible that you are trying to
use jSimuClass in a different thread from the one that was current when it
was allocated?

Signature

Bill Medland

kowald@molgen.mpg.de - 11 Oct 2006 08:46 GMT
> Could it be a problem with threading?  Is it possible that you are trying to
> use jSimuClass in a different thread from the one that was current when it
> was allocated?

Hm, I'm not sure. The DLL that calls the java class is a plugin for a
commercial application for which I have no source code. So I don't know
when and from where my dll is called.

But if jSimuClass would be called from a different thread, why would
this be a problem ?  What could happen? The error code I'm getting when
the C program crashes is something like:
"There was an unhandled exception. Access error when trying to read
address 0x00000090"

Axel
Bill Medland - 11 Oct 2006 14:52 GMT
>> Could it be a problem with threading?  Is it possible that you are trying
>> to use jSimuClass in a different thread from the one that was current
[quoted text clipped - 11 lines]
>
> Axel
Almost certainly that involves accessing a structure member where the
pointer to the structure is null.  Sounds to me like something is
uninitialised.
Signature

Bill Medland

Chris Uppal - 11 Oct 2006 10:30 GMT
> JNIEnv          *env;

It's usually a bad idea to store a JNIEnv pointer as a static, unless your
program is driving Java rather than being driven by Java.

A JNIEnv is only valid in one thread.

If your code has been called by Java, then that will provide a JNIEnv which you
should use (even if you are on the same thread as the one which saved the
original JNIEnv), since not all operations are valid on anything except the
current JNIEnv (I can't remember the details, I'm afraid -- the only /specific/
problem I remember is that JNI local refs must be released using the same
JNIEnv as created them).

If your code might be called in a different thread then you'll have to take
account of that in your design, and ask the JVM for the correct JNIEnv for
whatever thread you happen to be running on.  That's easier, of course, if you
are in control of the app's theading architecture.

BTW, just because some code works in some situations doesn't mean that code is
correct -- it may only mean that you got lucky (or unlucky, depending on how
you see it).

   -- chris
Bill Medland - 11 Oct 2006 14:41 GMT
>> JNIEnv          *env;
>
> It's usually a bad idea to store a JNIEnv pointer as a static, unless your
> program is driving Java rather than being driven by Java.

which was clear from the original post.

> A JNIEnv is only valid in one thread.

but as I remember it, is guaranteed to be valid on all calls in that thread

> If your code has been called by Java, then that will provide a JNIEnv
> which you should use (even if you are on the same thread as the one which
> saved the original JNIEnv), since not all operations are valid on anything
> except the current JNIEnv (I can't remember the details, I'm afraid -- the
> only /specific/ problem I remember is that JNI local refs must be released
> using the same JNIEnv as created them).

I'd be interested in the details.

> If your code might be called in a different thread then you'll have to
> take account of that in your design, and ask the JVM for the correct
[quoted text clipped - 7 lines]
>
>     -- chris

Signature

Bill Medland

Chris Uppal - 12 Oct 2006 12:38 GMT
[me:]
> > If your code has been called by Java, then that will provide a JNIEnv
> > which you should use (even if you are on the same thread as the one
[quoted text clipped - 4 lines]
>
> I'd be interested in the details.

I'm sorry, but I can't remember where in the spec it is, and a quick search
didn't locate it.  If it's going to come down to re-reading the entire spec
looking for it then you can do that as easily as I ;-)

This came up when I was setting up my JNI stuff some years ago.  I tried
porting my code to run with the IBM JMV, and it (helpfully) complained that I
was releasing local refs on the wrong JNIEnv.  I didn't believe that there was
such a restriction.  So I swore, and went looking in the spec for proof that
IBM was wrong -- unfortunately, what I found was proof that IBM was right
:-(   So I swore even more, and then almost completely re-wrote the
housekeeping in the lower layers of my stuff to obey the "new" rule.  As a
side-effect of that, my stuff now uses the "current" JNIEnv for all operations,
not just DeleteLocalRef() -- which is why I'm not all that interested in what
other restrictions there may be (if there are any at all), and the details have
faded from my mind.

Incidentally, I agree with your suggestion (elsethread) that the error message
the OP has now provided is indicative of an attempt to deference a NULL
pointer.

   -- chris
Bill Medland - 12 Oct 2006 17:00 GMT
> [me:]
>> > If your code has been called by Java, then that will provide a JNIEnv
[quoted text clipped - 10 lines]
> didn't locate it.  If it's going to come down to re-reading the entire
> spec looking for it then you can do that as easily as I ;-)

True.  BTW what do you regard as "the spec"?  I tried using the JNI
documentation that comes with Java and forgot that I had downloaded Sheng
Liang's "Programmer's Guide and Specification" which I find much better.

> This came up when I was setting up my JNI stuff some years ago.  I tried
> porting my code to run with the IBM JMV, and it (helpfully) complained
[quoted text clipped - 10 lines]
> interested in what other restrictions there may be (if there are any at
> all), and the details have faded from my mind.

Oh; OK.  I knew about that one (having read it more recently than you, I
expect). I was just getting an impression that you were suggesting that we
could not depend on the JNIEnv staying constant on a given thread, which I
thought was guaranteed (and thus allowed caching in a single-threaded
program).

> Incidentally, I agree with your suggestion (elsethread) that the error
> message the OP has now provided is indicative of an attempt to deference a
> NULL pointer.

Yes.  But I don't think it is the JNIEnv that is null.

Can the OP instruct the JVM to run with all that JNI protection code enabled
(the verbose:jni I presume; I have forgotten)

>     -- chris

Signature

Bill Medland

Chris Uppal - 13 Oct 2006 10:52 GMT
>  BTW what do you regard as "the spec"?  I tried using the JNI
> documentation that comes with Java and forgot that I had downloaded Sheng
> Liang's "Programmer's Guide and Specification" which I find much better.

In my case it would have been the version of the "JNI Specification" (plus
ammendements) which came with the JDK 1.3.  Obviously, I use the version which
comes with 1.5 these days ;-)

As far as I know, Liang's book includes the spec in toto, but I haven't checked
it word-for-word, and I don't know which version of the spec it is anyway.

> Can the OP instruct the JVM to run with all that JNI protection code
> enabled (the verbose:jni I presume; I have forgotten)

-Xcheck:jni

That's certainly worth trying.  One word of warning is that I think the
checking code in at least one version of 1.5 was buggy and reported errors
where there was none.  At least, I have some code which an earlier dot.dot
release reported as wrong, but I can't find anything wrong with it, and neither
1.4.x nor later versions of 1.5 report any problem. (I'm currently usng
1.5.0_06-b05).

Another thing that's worth trying if the OP has access to a sufficiently
up-to-date IBM JVM, is to try that.  The IBM error checking is (or was when I
last tried it -- back in 1.3 days) superior to Sun's.

   -- 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.