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 2006

Tip: Looking for answers? Try searching our database.

JNI Trouble calling FindClass from Worker thread

Thread view: 
maverick - 18 Jul 2006 02:45 GMT
Hello
I am able to get the class object when i call FindClass in the main
thread. Now when i spawn a worker thread and attempt the same call
after caching the JVM and creating a new Env . it fails and triggers an
exception on the Java side .

My code for a DLL looks like this

JMVM *jvm = NULL ;

..
DLLMain()
{
}

JNIEXPORT jint JNICALL Initialize
 (JNIEnv *pEnv, jclass)
{

  pEnv->GetJavaVM(&jvm);
  ASSERT(jvm!=NULL);

   jclass cls = pEnv->FindClass("demoflashplugin/views/Objfactory");

   if(cls!=NULL)
    AfxMessageBox("cls found");

 AfxBeginThread(WindowThread , NULL);

}

UINT WindowThread(LPVOID p)
{

    JNIEnv *env = NULL ;
    jclass cclass ;
    if(jvm!=NULL)
    {
        if (0==jvm->AttachCurrentThread((void**)&env,NULL))
        {
            if ((env)->ExceptionOccurred()) {
                AfxMessageBox("Exception occured");
                (env)->ExceptionDescribe() ;
            }
            if(env!=NULL)
            {
                AxMessageBox(getenv("CLASSPATH"));
                cclass = env->FindClass(demoflashplugin/views/Objfactory");
                if(cclass!=NULL)
                {
                AfxMessageBox("Class is not Null");
                }
                else
                AfxMessageBox("Class is s Null");
            }
            else
            {
                AfxMessageBox("env is NULL ");
            }

            AfxMessageBox("Finished checking for string");
        }
        else
        {
            AfxMessageBox("JVM IS  Null");
        }

           
    }
}
Chris Uppal - 18 Jul 2006 08:36 GMT
> I am able to get the class object when i call FindClass in the main
> thread. Now when i spawn a worker thread and attempt the same call
> after caching the JVM and creating a new Env . it fails and triggers an
> exception on the Java side .

>     jclass cls = pEnv->FindClass("demoflashplugin/views/Objfactory");
[...]
> cclass = env->FindClass(demoflashplugin/views/Objfactory");

Note that the second line won't compile -- it's worth double checking your real
code to see if you are using identical class names in both cases.

Other than that I don't see anything obviously wrong.

   -- chris
maverick - 18 Jul 2006 10:03 GMT
actually this does compile and I am able to verify the same by stepping
inside

> > I am able to get the class object when i call FindClass in the main
> > thread. Now when i spawn a worker thread and attempt the same call
[quoted text clipped - 11 lines]
>
>     -- chris
maverick - 18 Jul 2006 10:13 GMT
cclass = env->FindClass(demoflashplugin/views/Objfactory");

Yes this was a typo , make that
cclass = env->FindClass("demoflashplugin/views/Objfactory");

Sorry my mistake .

For some reason I cannot find the class from the thread . Inside Java
code my classpath is a .jar file . I would assume that the same
environment would be passed to the thread when i cache the JVM pointer
.  Looks like i ve really hit a stone and am not able to root cause
this . Really need some inputs for this  . i still believe its some
kinda classpath issue but  am not able to resolve it

> actually this does compile and I am able to verify the same by stepping
> inside
[quoted text clipped - 14 lines]
> >
> >     -- chris
Chris Uppal - 18 Jul 2006 10:57 GMT
> For some reason I cannot find the class from the thread . Inside Java
> code my classpath is a .jar file . I would assume that the same
> environment would be passed to the thread when i cache the JVM pointer

The JVM's classpath will be the same in all threads.

The only possibility that I can suggest is that the Java thread where the
FindClass() works is running with a custom classloader, not the primordial or
the application classloader.  That would happen if a custom classloader is used
to load the class from which the DLL is initially loaded (probably in its class
initialisation).   If that happened then that classloader might be able to find
Objfactory.class but the application classloader (which would be used by the
new thread's FindClass() as far as I understand this) would not be able to find
it (or worse, would find another version).

If that is the problem, then the simple solution would be to get references to
the classes you need in the DLL main(), convert them to "global" references (so
they can be used from any thread), and store them there.

If that's too inflexible, then I would be tempted to change the design a bit --
create a Java object (of a new class written for this purpose) who's job it is
to find your classes.  It's class would be loaded by the custom classloader,
and so that classloader would be used whenever it used Class.byName().  You
would then initialise your DLL with a (global) instance of that class, and
would use its findClass() method instead of the JNI FindClass().

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