Chamando o assembly .NET de Java: falhas da JVM

Eu tenho um .NET Assembly de terceiros e um grande aplicativo Java. Eu preciso chamar mothods fornecidos pela biblioteca de classes .NET do aplicativo Java. O assembly não está habilitado para COM. Eu pesquisei na net e até agora eu tenho o seguinte:

Código c # (cslib.cs):

using System;

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

compilado com (usando o .net 3.5, mas o mesmo acontece quando o 2.0 é usado):

csc /target:library cslib.cs

Código 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();
}

compilado com (usando ferramentas do VC 2008, mas o mesmo acontece quando ferramentas 2003 são usadas):

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

Código Java (CallCS.java):

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

Quando tento executar a classe java, a VM Java falha ao invocar o método (é capaz de carregar a biblioteca):

#
# 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

No entanto, se eu criar um aplicativo cpp simples que carregue o clib.dll e chame a função exportada Java_CallCS_callCS, tudo estará OK. Eu tentei isso em ambientes x86 e x64 e o resultado é o mesmo. Eu não tentei outras versões do Java, mas eu preciso que o código seja executado no 1.5.0.

Além disso, se eu modificar o clib.cpp para chamar apenas os métodos do sistema, tudo funciona bem, mesmo a partir do 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");
}

Para finalizar:

Eu sou capaz de chamar métodos do sistema de Java -> clib.dll -> mscorlib.dllEu sou capaz de chamar qualquer método de CPPApp -> clib.dll -> cslib.dllEu sou incapaz de chamar qualquer método de Java -> clib.dll -> cslib.dll

Estou ciente de uma solução que usa 1. acima - eu posso usar reflexão para carregar o assmebly e invocar métodos desejados usando apenas chamadas do sistema, mas o código fica confuso e estou esperando por uma solução melhor.

Eu sei sobre o projeto dotnetfromjava, que usa o método de reflexão, mas prefere não adicionar mais complexidade do que o necessário. Vou usar algo assim, se não houver outra maneira, no entanto.

Eu olhei ikvm.net também, mas meu entendimento é que ele usa sua própria JVM (escrita em C #) para fazer a mágica. No entanto, a execução de todo o aplicativo Java em sua VM não é uma opção para mim.

Obrigado.

questionAnswers(4)

yourAnswerToTheQuestion