De l'appelant .NET de l'assemblée de l'île de Java: JVM se bloque
J'ai une troisième partie .NET de l'Assemblée et une grande application Java. J'ai besoin d'appeler réflexes fournis par le .NET de la bibliothèque de classes de l'application Java. L'assemblée n'est pas COM-activé.
J'ai cherché sur le net et pour l'instant j'ai le texte suivant:
Code C# (cslib.cs):
using System;
namespace CSLib
{
public class CSClass
{
public static void SayHi()
{
System.Console.WriteLine("Hi");
}
}
}
compilé (à l'aide .net 3.5, mais le même phénomène se produit quand 2.0 est utilisé):
csc /target:library cslib.cs
De code C++ (clib.cpp):
#include <jni.h>
#using <CSLib.dll>
using namespace CSLib;
extern "C" _declspec(dllexport) void Java_CallCS_callCS(JNIEnv* env, jclass cls) {
CSLib::CSClass::SayHi();
}
compilé (à l'aide de VC 2008 outils, mais le même phénomène se produit lors de 2003 sont les outils utilisés):
cl /clr /LD clib.cpp
mt -manifest clib.dll.manifest -outputresource:clib.dll;2
Code Java (CallCS.java):
class CallCS {
static {
System.loadLibrary("clib");
}
private static native void callCS();
public static void main(String[] args) {
callCS();
}
}
Lorsque j'essaie d'exécuter la classe java, la machine virtuelle Java plante lors de l'invocation de la méthode (il est en mesure de charger la bibliothèque):
# # Une erreur inattendue a été détectée par l'Environnement d'Exécution Java: # # Erreur interne (0xe0434f4d), pid=3144, tid=3484 # # Java VM: Java HotSpot(TM) Client VM (10.0-b19 en mode mixte, le partage de windows-x86) # Problématiques cadre: # C [kernel32.dll+0x22366] # ... Java cadres: (J=compilé en code Java, j=interprété, Vv=VM code) j CallCS.callCS()V+0 j CallCS.principale([Ljava/lang/String;)V+0 v ~StubRoutines::call_stub
Cependant, si je crée une plaine rpc application qui charge clib.dll et appelle la fonction exportée Java_CallCS_callCS, tout est OK.
J'ai essayé sur les deux environnements x86 et x64 et le résultat est le même. Je n'ai pas essayé d'autres versions de Java, mais j'ai besoin le code à exécuter sur 1.5.0.
De plus, si je modifie clib.cpp pour appeler Système d'méthodes tout fonctionne très bien, même à partir de Java:
#include <jni.h>
#using <mscorlib.dll>
using namespace System;
extern "C" _declspec(dllexport) void Java_CallCS_callCS(JNIEnv* env, jclass cls) {
System::Console::WriteLine("It works");
}
Pour conclure:
- Je suis en MESURE de Système d'appel des méthodes de Java -> clib.dll -> mscorlib.dll
- Je suis en MESURE d'appeler les méthodes de CPPApp -> clib.dll -> cslib.dll
- Je suis INCAPABLE d'appeler les méthodes de Java -> clib.dll -> cslib.dll
Je suis conscient d'une solution de contournement qui utilise 1. ci-dessus - que je peux utiliser la réflexion pour charger la assmebly et d'appeler désiré méthodes utilisant uniquement les appels Système, mais le code est illisible et je suis l'espoir d'une meilleure solution.
Je sais à propos de dotnetfromjava projet, qui utilise la méthode de réflexion, mais qui préfèrent ne pas ajouter plus de complexité que de besoin. Je vais utiliser quelque chose comme cela si il n'y a pas d'autre moyen, cependant.
J'ai regardé ikvm.net aussi, mais ma compréhension est qu'il utilise sa propre JVM (écrit en C#) pour faire de la magie. Toutefois, l'exécution de l'ensemble de l'application Java sous son VM est pas une option pour moi.
Grâce.
Oui, le /clr option est spécifiée
OriginalL'auteur Kcats | 2008-09-26
Vous devez vous connecter pour publier un commentaire.
OK, le mystère est résolu.
La JVM blocage est dû à la non prise en charge du Système.IO.FileNotFoundException. L'exception est levée, car .NET de l'assemblée est recherché dans le dossier où l'appel de fichier exe réside.
Il semble que ma seule option est d'installer le .NET assembly dans le GAC (la dll de tierce partie ne avoir un nom fort).
Merci pour ce partage, en effet j'ai utilisé exactement la AssemblyResolve événement, mais il a oublié de mettre à jour la réponse.
OriginalL'auteur Kcats
Regarder jni4net, il va faire le travail dur pour vous.
Uniquement sur Windows
OriginalL'auteur user200245
Avez-vous regardé ikvm.NET qui permet de faire des appels entre les deux .NET et Java code?
OriginalL'auteur cruizer
J'étais tellement heureux de trouver cet article depuis que je suis coincé et a eu exactement ce problème.
Je veux contribuer au code, ce qui aide à surmonter ce problème.
Dans votre Java appel du constructeur de la méthode init, ce qui ajoute à la résolution de l'événement.
Mon expérience, il est nécessaire de faire appel à init PAS juste avant l'appel dans votre bibliothèque en c++ code, car en raison de problèmes de calendrier, il peut se bloquer néanmoins.
J'ai mis l'init d'appel dans ma classe java, le constructeur de la cartographie de la JNI appels, qui fonctionne très bien.
Code C++
Code Java
OriginalL'auteur dusselduck22