当前位置: 首页 > 面试题库 >

从Java调用.NET程序集:JVM崩溃

傅增
2023-03-14
问题内容

我有一个第三方.NET
Assembly和一个大型Java应用程序。我需要从Java应用程序调用.NET类库提供的方法。该程序集不支持COM。我已经搜索过网络,到目前为止,我有以下内容:

C#代码(cslib.cs):

using System;

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

编译使用(使用.net 3.5,但使用2.0时也会发生同样的情况):

csc /target:library cslib.cs

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

(使用VC 2008工具进行编译),但使用2003工具时也会发生以下情况:

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

Java代码(CallCS.java):

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

当我尝试运行Java类时,调用该方法时Java VM崩溃(它能够加载该库):

#
#Java Runtime Environment检测到意外错误:
#
#内部错误(0xe0434f4d),pid = 3144,tid = 3484
#
#Java VM:Java HotSpot(TM)客户端VM(10.0-b19混合模式,共享Windows-x86)
#问题框架:
#C [kernel32.dll + 0x22366]
#
...
Java框架:(J =编译后的Java代码,j =解释后的Vv = VM代码)
j CallCS.callCS()V + 0
j CallCS.main([Ljava / lang / String;)V + 0
v〜StubRoutines :: call_stub

但是,如果我创建一个加载clib.dll的普通cpp应用程序并调用导出的函数Java_CallCS_callCS,则一切正常。我已经在x86和x64环境中进行了尝试,结果是相同的。我没有尝试过其他版本的Java,但是我需要代码可以在1.5.0上运行。

此外,如果我将clib.cpp修改为仅调用System方法,那么即使从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");
}

总结一下:

  1. 我可以从Java-> clib.dll-> mscorlib.dll调用系统方法
  2. 我可以从CPPApp-> clib.dll-> cslib.dll调用任何方法
  3. 我无法从Java-> clib.dll-> cslib.dll调用任何方法

我知道上面有一种使用1.的解决方法-我可以使用反射来加载组件并仅使用系统调用来调用所需的方法,但是代码变得凌乱,我希望有一个更好的解决方案。

我知道dotnetfromjava项目,该项目使用了反射方法,但不希望增加不必要的复杂性。但是,如果没有其他方法,我将使用类似的方法。

我也看过ikvm.net,但是我的理解是它使用自己的JVM(用C#编写)来完成任务。但是,对于我来说,在其VM下运行整个Java应用程序是不可行的。

谢谢。


问题答案:

好了,谜团解决了。

JVM崩溃是由未处理的System.IO.FileNotFoundException引起的。因为在调用exe文件所在的文件夹中搜索.NET程序集,所以引发了异常

  1. mscorlib.dll位于全局程序集缓存中,因此可以正常工作。
  2. CPP应用程序exe与程序集位于同一文件夹中,因此它也可以工作。
  3. cslib.dll程序集位于java.exe文件夹中,位于GAC中的NOR中,因此它无法正常工作。

看来我唯一的选择是在GAC中安装.NET程序集(第三方dll的确有很强的名字)。



 类似资料:
  • 希望你做得很好。 我有一个C语言的JNI实现,其中一个C函数连接到当前JVM线程并回调一个Java方法,这实际上是在attachCurrentThread()函数调用时使JVM崩溃。我的实现基于链接中给出的答案,保持对JNIEnv环境的全局引用 线程创建部分,它将侦听套接字连接以接受事件并注入GetEvent函数。 回调函数 在接收到事件时执行GetEvent()后,我的JVM在AttachMon

  • 我正在尝试与Java和Cobol进行通信。我需要从Cobol调用一个Java程序(带有参数)。 我阅读了Microfocus的一些文档:http://supportline.microfocus.com/documentation/books/nx40/dijafc.htm http://supportline.microfocus.com/documentation/books/nx40/dij

  • JVM崩溃-“EXCEPTION\u ACCESS\u VIOLATION” 我使用Spring Boot制作了这个CLI工具,需要很长时间才能运行。我通常让它运行一夜。然后,有好几次我遇到了这个JVM崩溃,我不知道该在那里寻找什么。我看到过其他错误报告,但无法将其与我的报告联系起来。 你能看一下这个日志文件吗?请记住,我一直有应用程序内存泄漏的问题。。。当我以为已经解决了内存泄漏问题时,我开始遭

  • 我正在一个非常低配置的机器上工作,其中JVM有时会崩溃。 java应用程序名为application。jar,从本地流媒体服务器播放高清视频。该应用程序运行在悬挂在Rest室中的嵌入式win7触摸计算机上。 当堆大小超过某一时间,并且错误内存不足时,JVM将关闭。 我想重新启动我的应用程序.jar每当JVM崩溃。 这是可能的。然后如何做到呢? 谢了。 编辑:使用尝试捕获进行包装不起作用,因为jvm

  • 问题内容: 我是一名.Net开发人员,开始为Android开发Java,并想知道考虑诸如.Net程序集之类的Java软件包是否正确。 问题答案: 没有。 最好的比较是与Java ARchive(Jar)文件。Java使用包来控制名称空间,并且与C#的名称空间非常相似。 这是我比较环境的方式