Wywoływanie zestawu .NET z Java: JVM ulega awarii

Mam zespół .NET innej firmy i dużą aplikację Java. Muszę wywołać mothods dostarczone przez bibliotekę klas .NET z aplikacji Java. Zespół nie ma włączonej obsługi COM. Przeszukałem sieć i jak dotąd mam następujące:

Kod C # (cslib.cs):

using System;

namespace CSLib
{
    public class CSClass
    {
        public static void SayHi()
        {
            System.Console.WriteLine("Hi");
        }
    }
}

skompilowany z (przy użyciu .net 3.5, ale to samo dzieje się, gdy używany jest 2.0):

csc /target:library cslib.cs

Kod 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();
}

skompilowane (przy użyciu narzędzi VC 2008, ale to samo dzieje się, gdy używane są narzędzia 2003):

cl /clr /LD clib.cpp
mt -manifest clib.dll.manifest -outputresource:clib.dll;2

Kod Java (CallCS.java):

class CallCS {
    static {
       System.loadLibrary("clib");
    }
    private static native void callCS();
    public static void main(String[] args) {
        callCS();
    }
}

Gdy próbuję uruchomić klasę java, Java VM ulega awarii podczas wywoływania metody (może załadować bibliotekę):

#
# An unexpected error has been detected by Java Runtime Environment:
#
#  Internal Error (0xe0434f4d), pid=3144, tid=3484
#
# Java VM: Java HotSpot(TM) Client VM (10.0-b19 mixed mode, sharing windows-x86)
# Problematic frame:
# C  [kernel32.dll+0x22366]
#
...
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  CallCS.callCS()V+0
j  CallCS.main([Ljava/lang/String;)V+0
v  ~StubRoutines::call_stub

Jeśli jednak utworzę prostą aplikację cpp, która ładuje clib.dll i wywołuje wyeksportowaną funkcję Java_CallCS_callCS, wszystko jest w porządku. Próbowałem tego zarówno w środowiskach x86, jak i x64, a wynik jest taki sam. Nie próbowałem innych wersji Java, ale potrzebuję kodu, aby uruchomić go na 1.5.0.

Co więcej, jeśli zmodyfikuję clib.cpp, aby wywołać tylko metody systemowe, wszystko działa dobrze nawet z poziomu 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");
}

Zapakować:

Jestem w stanie wywołać metody systemowe z Java -> clib.dll -> mscorlib.dllJestem w stanie wywołać dowolne metody z CPPApp -> clib.dll -> cslib.dllNie jestem w stanie wywołać żadnych metod z Java -> clib.dll -> cslib.dll

Jestem świadomy obejścia, które używa 1. powyżej - mogę użyć refleksji, aby załadować assmebly i wywołać pożądane metody używając tylko wywołań systemowych, ale kod staje się bałagan i mam nadzieję na lepsze rozwiązanie.

Wiem o projekcie dotnetfromjava, który wykorzystuje metodę refleksji, ale wolę nie dodawać więcej złożoności niż jest to konieczne. Jednakże użyję czegoś takiego, jeśli nie ma innego sposobu.

Spojrzałem także na ikvm.net, ale rozumiem, że używa on własnej JVM (napisanej w C #) do magii. Jednak uruchomienie całej aplikacji Java w jej VM nie jest dla mnie opcją.

Dzięki.

questionAnswers(4)

yourAnswerToTheQuestion