3 Replies Latest reply: Oct 4, 2011 4:14 PM by jschellSomeoneStoleMyAlias RSS

    Invoke Java in separate shell

    875447
      I have my invocation code from C++ side. Here, I trigger a method t_methodName in pPathToJar. Lets say the invoked jar executable is a simple "HelloWorld.jar" and just prints "HelloWord" in the console. Everything works properly!

      [JAVA]
      #include <jni.h> 
      #include "ExternJar.h"   
      
      #pragma comment (lib,"C:\\Program Files\\Java\\jdk1.6.0_26\\lib\\jvm.lib")   
      /// Constructor 
      ExternJar::ExternJar(const char* pPathToJar, const char* pPathToLib, const char *t_argv, const char *t_path2Package, const char* t_methodName) 
      {
          int oi = 0;
          options[oi++].optionString = const_cast<char*>(pPathToJar);
          vm_args.nOptions = oi;
          vm_args.version = JNI_VERSION_1_6;
          vm_args.options = options;
          vm_args.ignoreUnrecognized = JNI_FALSE;
            argumentString = t_argv;
          path2Jar = pPathToJar;
          path2Lib = pPathToLib;
          packagePath = t_path2Package;
          methodName = t_methodName;
          debugMode = 0;
      }
      
      void ExternJar::setClassName() 
      {
            switch(JNI_CreateJavaVM( &jvm,(void **)&env, &vm_args)) {
             case JNI_OK:          printf("\nJVM created --> Ready ...\n");    
            }
            if( NULL == (cls = env->FindClass(packagePath)) ) printf("\nCan't find class %s\n", packagePath);
            else printf("\nClass %s found!\n", packagePath); 
      }
      
      void ExternJar::setArgCV() 
      {
          if (!argumentString) return;
          this->applicationArg0 = env->NewStringUTF(argumentString);
          this->applicationArgs = env->NewObjectArray(1, env->FindClass("java/lang/String"), applicationArg0);
          env->SetObjectArrayElement(applicationArgs, 0, applicationArg0);
      }
      
      void ExternJar::setMethodName() {
          mid = env->GetStaticMethodID(cls, methodName, "([Ljava/lang/String;)V");
          printf("\nMethod name set to: %s", methodName); 
      }
      
      void ExternJar::callXMethod() 
      {
             printf("\nCall now \n%s(\"%s\"):", methodName, argumentString);
             if (mid != NULL) env->CallStaticVoidMethod(cls, mid, applicationArgs);
             else printf("\nMethod %s corrupted!\n", mid); 
      }
      
      JavaVM * ExternJar::getVM() {    return this->jvm; }
      
      void * ExternJar::getEnv() {    return this->env; }
      #
      
      bool ExternJar::destroyVM() 
      {
          printf("\nDestroy VM now!");
          if ( this->getVM()->DestroyJavaVM() == 1 ) return true;
          else return false; 
      }
      
      void ExternJar::run()
      {
          this->setClassName();
          this->setArgCV();
          this->setMethodName();
          this->callXMethod();
      } 
      [JAVA]

      My problem is: When I invoke any jar from C++ side, it is executed in the same commandline-window as my invoking C++-Project.
      I would like to invoke that jar in a separate cmd.exe.
      Is there any possibility by JNI side?

      I hope you understood what I was trying to make clear. Thank you.

      Cheers Huck
        • 1. Re: Invoke Java in separate shell
          796440
          huckleberry wrote:
          My problem is: When I invoke any jar from C++ side, it is executed in the same commandline-window as my invoking C++-Project.
          I would like to invoke that jar in a separate cmd.exe.
          So then you don't want to invoke command XYZ. Instead, you want to invoke cmd.exe, and tell it to invoke command XYZ. I believe what you want is then something like:
          cmd /C XYZ
          • 2. Re: Invoke Java in separate shell
            875447
            Yes, I can trigger in Qt:
            QString program = "C:/Program Files/Java/jdk1.7.0/bin/java.exe";
            QStringList arguments; 
            arguments << "-jar C:\\Path\\external.jar -m more_switchs";  
            QProcess *myProcess = new QProcess(); 
            myProcess->start(program, arguments); 
            But I was hoping that there was a JNI specific thing as:
            ExternJar::ExternJar(const char* pPathToJar, const char* pPathToLib, const char *t_argv, const char *t_path2Package, const char* t_methodName) 
            {
            //.... and then something like
               vm_args.newProcess = JNI_TRUE;
            }
            • 3. Re: Invoke Java in separate shell
              jschellSomeoneStoleMyAlias
              huckleberry wrote:
              But I was hoping that there was a JNI specific thing as:
              The point of JNI is to run it in the same process. So running it in another process is pointless.

              You can start your application in another process.
              Or you can use Runtime.exec() or ProcessBuilder, in JNI to invoke another process.