Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 5 of 5

Thread: JVM launched from C++ program : problem with GUI calls

  1. #1
    Junior Member
    Join Date
    Apr 2014
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default JVM launched from C++ program : problem with GUI calls

    Dear all,

    I am a C++ programmer and I use JNI to instanciate a JVM in my application in order to use a third-party java application.

    When launching the third party application directly from java, it works fine, but when I try to start it from a JVM instanciated from my C++ program, it fails with an infinite loop the first time it tries to open a dialog. All java stuff before the first java dialog is executing fine.

    The strange thing is that if I add the following line at the first line of the java function invoked from C++, then the whole java library is properly executing without any problem, including all gui stuff :
    javax.swing.JOptionPane.showMessageDialog(null,"He llo World from JAVA !");

    For debug, it's fine like that, but for release, it's a bit odd to let this dialog...

    So, maybe am I missing something in the JVM initialisation, but as the above slightly modified java library version is working, I am out of idea on what looking for ?

    Does someone has an idea of what may be wrong ?

    Thanks in advance,

    Brice


  2. #2
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    5,517
    My Mood
    Mellow
    Thanks
    215
    Thanked 698 Times in 680 Posts

    Default Re: JVM launched from C++ program : problem with GUI calls

    Welcome to the Forum! Please read this topic to learn how to post code correctly and other useful tips for newcomers.

    Isn't this a C++ question? Perhaps a C++ forum would be a better place to get an answer. If you wish to pursue it further here, post the Java code that results in the infinite loop. If the code is too lengthy, simplify your code and post an example that exhibits the same behavior.

    You might also describe your observations that convinced you that the misbehaving code results in an infinite loop. Have you profiled it to see what is happening with memory and the processor(s) while this behavior is occurring?

  3. #3
    Junior Member
    Join Date
    Apr 2014
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: JVM launched from C++ program : problem with GUI calls

    Hello GregBrannon,

    And thanks for your answer.

    I am not convinced that my problem is related to java code. I am even pretty sure that the problem comes from the JNI stuff that I use in my C++ code to launch a JVM instance, but I think that a java forum is more appropriate as, in all cases, my problem is not C++ specific, but at least JNI-related.

    I fear that I cannot reduce the example because everything occurs in a library that I did not write. The key point is that this library works fine with a lot of users when used standalone (I mean when you execute it directly from a java context). My problem is that I try to execute it from a C++ context. I suppose I initialise something wrong.

    Here is my java entry point that does not work :
    public class Test {
     
    	public static String exec(String coucou)
    	{
    		EHealthTest.execute();
    		return "Done !";
    	}
    }

    and here is the one that works :
    public class Test {
     
    	public static String exec(String coucou)
    	{
    		javax.swing.JOptionPane.showMessageDialog(null,"Hello World from JAVA !"); 
    		EHealthTest.execute();
    		return "Done !";
    	}
    }

    The C++ code that launches the JVM is the following :
     
    static void CheckForJNIException(JNIEnv* m_JVMEnv)
    {
       jthrowable expt = m_JVMEnv->ExceptionOccurred();
       if (expt != NULL) {
           m_JVMEnv->ExceptionClear();
           jmethodID toString = m_JVMEnv->GetMethodID(m_JVMEnv->FindClass("java/lang/Object"), "toString", "()Ljava/lang/String;");
           jstring estring = (jstring) m_JVMEnv->CallObjectMethod(expt, toString);
           jboolean isCopy;
           std::string message = m_JVMEnv->GetStringUTFChars(estring, &isCopy);
           throw MyException("TODO", "TODO", MyString("%s", message.c_str()));
       }
    }
     
    JVM::JVM(const MyArray<MyString>& class_path)
       :jvm(NULL),
        env(NULL)
    {
       /* First, try to determine version of java installed on computer */
       wxRegKey jvm_runtime_environment_key(wxRegKey::HKLM, "SOFTWARE\\JavaSoft\\Java Runtime Environment");
       if (jvm_runtime_environment_key.Exists() &&
           jvm_runtime_environment_key.HasValue("CurrentVersion"))
       {
          /* Retrieve version */
          wxString version;
          if (jvm_runtime_environment_key.QueryRawValue("CurrentVersion", version))
          {
             /* Now, try to get location of client lib */
             wxRegKey jvm_version_info(wxRegKey::HKLM,
                                       MyString("SOFTWARE\\JavaSoft\\Java Runtime Environment\\%s",
                                                MyString(version).GetCString()));
             if (jvm_version_info.Exists() &&
                   jvm_version_info.HasValue("RuntimeLib"))
             {
                /* Get location of runtime */
                wxString runtime_location;
                if (jvm_version_info.QueryRawValue("RuntimeLib", runtime_location))
                {
                   /* Get path */
                   MyString directory_path = MyFileSystemAccess::GetFileName(MyString(runtime_location)).FilePath;
     
                   /* Update Windows path */
                   MyString path(wxString(wxGetenv("PATH")));
                   path.Append(";%s", directory_path.GetCString());
                   wxSetEnv("PATH", path.GetCString());
     
                   /* Now, try to load dll */
                   if (jvm_dll.Load("jvm", wxDL_NOW))
                   {
                      /* Load all necessary symbols */
                      dll_ptrs.CreateJavaVM = (jint(JNICALL*)(JavaVM**,void**,void*))jvm_dll.GetSymbol("JNI_CreateJavaVM");
     
                      /* Prepare */
                      if (dll_ptrs.CreateJavaVM)
                      {
                         /* prepare classpath */
                         MyString& class_path_str("-Djava.class.path=");
                         for (uint32 i = 0; i < class_path.GetSize(); i++)
                         {
                            if (i > 0) class_path_str.Append(";");
                            class_path_str.Append(class_path.GetElement(i));
                         }
     
                         /* init JVM */
                         JavaVMInitArgs args;
                         JavaVMOption options[3];
     
                         args.version = JNI_VERSION_1_2;
                         args.nOptions = 3;
                         options[0].optionString = (char*)class_path_str.GetCString();
                         options[1].optionString = "-verbose:jni";
                         options[2].optionString = "-Xcheck:jni";
                         args.options = options;
                         args.ignoreUnrecognized = JNI_FALSE;
     
                         dll_ptrs.CreateJavaVM(&jvm, (void **)&env, &args);
                         CheckForJNIException(env);
                         if (jvm != NULL)
                         {
                            wxMessageBox("VM Loaded !");
                            return;
                         }
                      }
                   }
                }
             }
          }
       }
     
       throw NoVMFound();
    }
     
    JVM::~JVM()
    {
       if (jvm) jvm->DestroyJavaVM();
    }
     
    MyString JVM::Invoke(const MyString& class_path, const MyString& method_name, const MyString& argument)
    {
       /* Correct class path, if needed */
       MyString corrected_path = class_path;
       corrected_path.Replace(".", "/");
     
       jclass target_class = env->FindClass(corrected_path.GetCString());
       CheckForJNIException(env);
       if (target_class)
       {
          jmethodID target_method = env->GetStaticMethodID(target_class, method_name.GetCString(), "(Ljava/lang/String;)Ljava/lang/String;");
          CheckForJNIException(env);
          if (target_method)
          {
             jstring target_method_arg = env->NewStringUTF(argument.GetCString());
             CheckForJNIException(env);
             if (target_method_arg)
             {
                jstring result = (jstring)env->CallStaticObjectMethod(target_class, target_method, target_method_arg);
                CheckForJNIException(env);
                if (result)
                {
                   return ToString(env, result);
                }
             }
          }
       }
     
       throw MethodInvocationError();
    }
     
    MyString JVM::ToString(JNIEnv *env, jstring name)
    {
       const char *str= env->GetStringUTFChars(name,0);
       MyString result("%s", str);
       env->ReleaseStringUTFChars(name, str);
       return result;
    }

    The point that makes me think that there is an infinite loop is that when I run my app under a debugger, with version that bugs, it continuously generates an Access violation exception (that seems to be what happens when java encounters a null pointer exception). But from the debugger, I cannot figure out what happens exactly. Note that this happens in JVM stuff and the C++ call to CallStaticObjectMethod never returns.

    The key point that I find very strange is that simply adding the java line that displays a dialog before launching the java library stuff solves the problem.

    Note that the java library performs log and, from this log, I can see that before going into its infinite loop, it performs a lot of processing without any problem and that everything goes wrong the first time this library tries to open a dialog.

    All this makes me think that the problem comes from the fact that I do not initialise something correctly in my JNI, preventing the GUI stuff of java to properly work, but that's just a guess...

  4. #4
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    5,517
    My Mood
    Mellow
    Thanks
    215
    Thanked 698 Times in 680 Posts

    Default Re: JVM launched from C++ program : problem with GUI calls

    Thanks for the additional detail. Well said.

    I get several results Googling "launch jvm from c++" and a few others if removing the '++'. Have you checked those out?

  5. #5
    Forum VIP
    Join Date
    Jul 2010
    Posts
    1,676
    Thanks
    25
    Thanked 329 Times in 305 Posts

    Default Re: JVM launched from C++ program : problem with GUI calls

    Do you have any idea where the null pointer is being thrown from?
    If you did not initialize something correctly, finding the line of code the null pointer is coming from might at least tell us *what* hasn't been initialized.

    Also, does only JOptionPane solve the issue? What if you just create a new JFrame and set it visible? If it only works with JOptionPane, maybe JOptionPane is initializing whatever has been forgotten.
    NOTE TO NEW PEOPLE LOOKING FOR HELP ON FORUM:

    When asking for help, please follow these guidelines to receive better and more prompt help:
    1. Put your code in Java Tags. To do this, put [highlight=java] before your code and [/highlight] after your code.
    2. Give full details of errors and provide us with as much information about the situation as possible.
    3. Give us an example of what the output should look like when done correctly.

    Join the Airline Management Simulation Game to manage your own airline against other users in a virtual recreation of the United States Airline Industry. For more details, visit: http://airlinegame.orgfree.com/

Similar Threads

  1. Java SE 7 OCA Training Lab Full Version Launched
    By treacyjane in forum The Cafe
    Replies: 0
    Last Post: November 4th, 2011, 08:57 AM
  2. All softwares use java can not be launched ? Using windows 7
    By IT_Fan in forum Java Theory & Questions
    Replies: 2
    Last Post: June 23rd, 2011, 12:22 PM
  3. could not open `C:\Program Files\Java\jre6\lib\amd64\jvm.cfg
    By miaaa00 in forum Java Theory & Questions
    Replies: 1
    Last Post: March 29th, 2011, 12:45 AM
  4. [SOLVED] Executable .jar file isn’t launched after being double-clicked
    By voltaire in forum Java Theory & Questions
    Replies: 6
    Last Post: May 18th, 2010, 03:37 PM
  5. Replies: 3
    Last Post: February 1st, 2010, 12:24 AM