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

Tip: Looking for answers? Try searching our database.

Infinite loop while calling JNI_CreateJavaVM (creating a JavaVM from C++)

Thread view: 
proy@conceptualspeech.com - 28 Dec 2005 14:04 GMT
I have a beautiful (that's at least what I think) piece of code that
soft-links to jvm.dll so that a JavaVM instance is created from C++.
The problem is that JNI_CreateJavaVM never returns! Would anyone have
some pointers to let me know what may be wrong in my code?

While referring to the code bellow, dEntryPoint2 is obtained
successfuly from the Dll, it is called, but stays into an infinite loop
(never comes back).

#include <jni.h>

JavaVM *CJavascript::m_JavaVM = NULL;
jclass CJavascript::m_class;
vector<CJavascript*> g_allObjects;
int gProcessCount = 0;
HMODULE CJavascript::m_java_dll = NULL;

typedef jint (JNICALL JNI_GetCreatedJavaVMs_t)(JavaVM **, jsize,
jsize*);
typedef jint (JNICALL JNI_CreateJavaVM_t)(JavaVM **pvm, void **penv,
void *args);

#define MY_CLASSPATH "js.jar:JavaScriptExecution.jar:."

bool EnsureJavaLaunched(JNIEnv *&dEnv)
{
  dEnv = NULL;
  if (CJavascript::m_JavaVM == NULL)
  {
     jint ret;
     jmethodID mid;
     jsize nVMs = 0;
     if (CJavascript::m_java_dll == NULL)
     {
        HKEY openkey = NULL;
        DWORD type;
        DWORD size;
        string fullKeyName;
        if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\JavaSoft\\Java
Runtime Environment", 0, KEY_READ, &openkey) == ERROR_SUCCESS)
        {
           char buffer[1024];
           size = sizeof(buffer);
           if (RegQueryValueEx(openkey, "CurrentVersion", NULL, &type,
(LPBYTE)&buffer[0], &size) == ERROR_SUCCESS)
           {
              fullKeyName = "SOFTWARE\\JavaSoft\\Java Runtime
Environment\\";
              fullKeyName += buffer;
              RegCloseKey(openkey);
              openkey = NULL;
              if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
fullKeyName.c_str(), 0, KEY_READ, &openkey) == ERROR_SUCCESS)
              {
                 size = sizeof(buffer);
                 if (RegQueryValueEx(openkey, "RuntimeLib", NULL,
&type, (LPBYTE)&buffer[0], &size) == ERROR_SUCCESS)
                 {
                    CJavascript::m_java_dll = LoadLibraryEx(buffer,
NULL, 0);
                 }
              }
           }
           if (openkey != NULL)
           {
              RegCloseKey(openkey);
           }
        }
     }
     if (CJavascript::m_java_dll != NULL)
     {
        JNI_GetCreatedJavaVMs_t *dEntryPoint =
(JNI_GetCreatedJavaVMs_t*)GetProcAddress(CJavascript::m_java_dll,
"JNI_GetCreatedJavaVMs");
        if (dEntryPoint != NULL)
        {
           if (!((dEntryPoint(&CJavascript::m_JavaVM, 1, &nVMs) == 0)
&& (nVMs == 1)))
           {
              JavaVMInitArgs vm_args;
              JavaVMOption options[3];
              char buffer[1024];

              options[0].optionString = "-Djava.compiler=NONE";
  /* disable JIT */
              strcpy(buffer, "-Djava.class.path=");
              strcat(buffer, MY_CLASSPATH);
              options[1].optionString = buffer;
  /* user classes */
              options[2].optionString = "-verbose:jni";
  /* print JNI-related messages */

              vm_args.version = JNI_VERSION_1_4;
              vm_args.options = options;
              vm_args.nOptions = 3;
              vm_args.ignoreUnrecognized = FALSE;
              JNI_CreateJavaVM_t *dEntryPoint2 =
(JNI_CreateJavaVM_t*)GetProcAddress(CJavascript::m_java_dll,
"JNI_CreateJavaVM");
              if (dEntryPoint2 != NULL)
              {
                 ret = dEntryPoint2(&CJavascript::m_JavaVM,
(void**)&dEnv, &vm_args);
                 if ((ret >= 0) && (CJavascript::m_JavaVM != 0) &&
(dEnv != 0))
                 {
                    jclass clazz =
dEnv->FindClass("JavaScriptExecution");
                    if (clazz != NULL)
                    {
                       mid = dEnv->GetStaticMethodID(clazz, "main",
"([Ljava/lang/String;)V");
                       if (mid != NULL)
                       {
                          dEnv->CallStaticVoidMethod(clazz, mid,
NULL);
                       }
                    }
                 }
              }
           }
        }
     }
  }
  if ((dEnv == NULL) && (CJavascript::m_JavaVM != NULL))
  {
     CJavascript::m_JavaVM->AttachCurrentThread((void**)&dEnv, NULL);
  }
  return (dEnv != NULL);
}

BOOL APIENTRY DllMain( HANDLE,
                      DWORD  ul_reason_for_call,
                      LPVOID
                    )
{
  switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
        case DLL_THREAD_ATTACH:
        {
           JNIEnv *dEnv;
           gProcessCount++;
           // Launch java daemon
           EnsureJavaLaunched(dEnv);
        }
        break;
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
        {
           gProcessCount--;
           if ((gProcessCount == 0) && (CJavascript::m_JavaVM !=
NULL))
           {
              CJavascript::m_JavaVM->DestroyJavaVM();
           }
        }
            break;
   }
   return TRUE;
}
Chris Uppal - 03 Jan 2006 10:59 GMT
> I have a beautiful (that's at least what I think) piece of code that
> soft-links to jvm.dll so that a JavaVM instance is created from C++.
> The problem is that JNI_CreateJavaVM never returns! Would anyone have
> some pointers to let me know what may be wrong in my code?

I found it impossible to follow the code, and eventually just gave up.
However, if you are still having problems then I suggest two avenues to check.

One is that -- as far as I can tell -- you are not doing anything /too/ odd in
the way you create and use your JMV, but it does look as if you are calling
JNI_GetCreatedJavaVMs() before you have ever called JNI_CreateJavaVM().  I
don't /think/ that's wrong, but it is unusual; it might be worth changing
things around so you don't do that, and see what happens.   Similarly, I'm a
bit suspicious about that call to AttacchCurrentThread() right at the end of
EnsureJavaLaunched().  By the time we reach that call, I have completely lost
any sense of how we have got there, so it may actually be completely fine, but
it's something I'd double check too.

The other is that I have never tried using the JVM from a DLL.  It's a long
shot, but I'd try converting this code into a standalone .EXE and see if it
still failed.

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



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