1

Salut les gens hehe
Dans le même programme C++ je n'arrive pas à ouvrir successivement deux JVM.
La première fois ça se passe très bien, la seconde ça échoue lamentablement.

Voici le test case :
   for ( int i= 0 ; i < 2 ; ++i ) {
      const int nbOptions= 1 ;
      JavaVMOption* optionsJVM(new JavaVMOption[nbOptions]) ;
      optionsJVM[0].optionString= "-Djava.class.path=C:/.../class" ;
      optionsJVM[0].extraInfo= NULL ;


      JavaVMInitArgs vm_args ; /* JDK/JRE 6 VM initialization arguments */

      vm_args.version= JNI_VERSION_1_6 ;
      vm_args.nOptions= nbOptions ;
      vm_args.options= optionsJVM ;
      vm_args.ignoreUnrecognized= false ;


      /* load and initialize a Java VM, return a JNI interface pointer in jniEnv */
      union {
         void* voidEnv ;
         JNIEnv* jniEnv ;
      } env ;
      JavaVM* jvm ;
      jint ret= JNI_CreateJavaVM(&jvm, &(env.voidEnv), &vm_args) ;
      delete[] optionsJVM ;

      std::cout << "JNI_CreateJavaVM status: " << (ret==JNI_OK?"success":"fail") << " (ret=" << ret << ")" << std::endl ;

      if ( ret == JNI_OK ) {
         jint retDestroy= jvm->DestroyJavaVM() ;
         std::cout << "DestroyJavaVM status: " << (retDestroy==0?"success":"fail") << " (retDestroy=" << retDestroy << ")" << std::endl ;
      }
   }



us: fail (ret=-1)
et le résultat : JNI_CreateJavaVM status: success (ret=0)
DestroyJavaVM status: success (retDestroy=0)
JNI_CreateJavaVM stat



Je sais qu'on ne peut pas créer plus d'une VM dans un processus, mais en la détruisant avant d'en faire une autre, ça devrait passer, non ? Toutefois, d'après http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/invocation.html#destroy_java_vm, c'est pas très clair si la destruction est vraiment implémentée ou pas... (je suis en JAVA 6)
The JDK/JRE still does not support VM unloading, however.
Enfin, à la rigueur, si, c'est clair mais ça me parait étrange que ça ne soit vraiment pas supporté trifus
Avez-vous de l'expérience sur ce point ?

Du coup, je pense que je vais n'en créer qu'une seule, la laisser vivre (dans une DLL) et m'arranger avec un attachCurrentThread().
Est-ce bien ce qu'il faut faire ?
Merci d'avance happy

2

bon mais t'as fini de faire des trucs aussi tordus? grin

vu les conditions, t'as pas tellement d'autres choix que ta méthode actuelle. Il te faut absolument lancer des VM a partir de code natif? tu peux vraiment pas faire l'inverse? grin

3

Pour ce soir, oué, j'ai fini : je rentre à ma maison embarrassed

Oué il le faut. En fait, le point d'entrée est... du VBA Excel, qui utilise la DLL (un composant COM) qui attaque une JVM locale qui se connecte à un JBOSS distant tripo

Bon, là ça fonctionne même pour des appels multiples sauf que :
[li]si j'appelle le detachCurrentThread() ça bloque dedans confus (du moins je crois, en tout cas ça ne rend pas la main au VB)
[li]si je n'appelle pas detachCurrentThread(), ça bloque Excel en arrière plan lors de sa fermeture (sans doute à cause du déchargement du composant COM via la méthode ExitInstance dans laquelle je fais un appel à DestroyJavaVM (DestroyJavaVM attendant que tous les detachCurrentThread soient appelés d'après ce que j'ai compris)

Une solution simple/gore serait sans doute de n'appeler ni les detachCurrentThread ni DestroyJavaVM et de laisser Excel et Windows tout fermer, mais bon... grin

4

awww mon pauvre tsss

si ça marche mieux, pourquoi pas...

t'es plus à ça près vu l'usine à gaz qui se dessine grin

(et y'a pas moyen de faire direct du SOAP en VBA, quitte a passer par un machin a base de winsock ?)

5

Quand j'y repense, il me semble que j'avais mon code de test qui faisait quand même le detachCurrentThread et que ça fonctionnait... Enfin je ne sais plus trop, on verra demain...

(peut-être, je ne sais pas ; là ce qu'on fait c'est qu'on utilise les classes du client java habituel pour utiliser les EJB)

6

oui oui j'ai bien compris, ça évite de recoder un truc déja fait (au moins dans la tête d'un chef de projet grin)