我有Java通过JNA调用C ++ / CLR库。当附加到C#DLL(使用#using< myC#lib.dll>)时,C#DLL 必须在System32中,没有别的办法,否则JVM会崩溃(原因很明显)。
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (os_windows_x86.cpp:149), pid=9932, tid=7464
# guarantee(result == EXCEPTION_CONTINUE_EXECUTION) failed: Unexpected result from topLevelExceptionFilter
#
# JRE version: 6.0_26-b03
# Java VM: Java HotSpot(TM) 64-Bit Server VM (20.1-b02 mixed mode windows-amd64 compressed oops)
# An error report file with more information is saved as:
# (log dir)
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
听起来像路径问题,对吧?好吧,这里有趣的地方:
这有效:
C:>设置PATH = C:\ Program Files \ Java \ jre6 \ bin; C:\ workspace \ bin \ plugins \ 64; c:\ Windows \ System32
这不是:
C:>设置PATH = C:\ Program Files \ Java \ jre6 \ bin; C:\ workspace \ bin \ plugins \ 64
是的,该库位于c:\ workspace \ bin \ plugins \ 64
中请注意,如果system32包含在路径中,它会找到我的库,因此它正确地挖掘了PATH目录(或者看起来似乎如此),但是如果我直接将它放在我的DLL所在的工作区中,它就无法运行它。我怀疑这是因为它是一个.NET DLL(将它注册到GAC并没有修复它,但如果它确实无法修复它),我觉得它只是一个普通的库查找问题。
我是否遗漏了Java可能对我的图书馆搜索路径所做的事情?我不能保证我有能力写入System32(更不用说我需要做一些自动化的东西,并希望远离操作系统目录远离FAR。)
如果我的C#DLL不在c:\ Windows \ System32中,而是在C:\ workspace \ bin \ plugins \ 64中,这不会起作用,所以采取我的愚蠢假设我可以将System32排除在等式之外。
C:>设置PATH = C:\ Program Files \ Java \ jre6 \ bin; C:\ workspace \ bin \ plugins \ 64; c:\ Windows \ System32
将DLL移回c:\ windows \ system32可以使其正常工作。
如果它有任何区别,如果它从Eclipse而不是命令行运行,它将不会运行 ...从Eclipse运行的System.getenv(“PATH”)显示我的全部路径,从C ++ / CLR DLL中删除C#DLL允许它运行。
所以它完全是.NET DLL,从命令行运行Java,.NET DLL必须在System32中,并且根本不会在Eclipse中运行。
如果从C ++ / CLR DLL中删除.NET DLL,它可以随时随地运行。
在GAC注册时似乎工作正常(时间感觉不好,我发誓之前没有工作),并且与此问题有关:
Calling .NET assembly from Java: JVM crashes
现在看看我是否可以让AssemblyResolve在C ++ / CLR上运行,由于它是一个库,这非常困难。
答案 0 :(得分:1)
你的.Net库显然有依赖关系。我当然期望的一个依赖是mscoree.dll,它位于System32中。我还要仔细检查你的DLL或其任何依赖项中是否有CPU限制(看到“64位服务器”)。
答案 1 :(得分:0)
好的,注册GAC修复它,所以我写了一个非常简单的程序,用GAC注册DLL(gacutil.exe不可再发行)。
我将它包含在Java应用程序中,它可以在运行时注册库。
我无法使用GAC(我从这里插入非GAC注册库,为什么要处理复杂的动态绑定),所以我使用Assembly Binder Log Entry Viewer来显示它在哪里搜索库,我已经使用我的应用程序打包了JRE,因此我可以在运行时轻松地将.NET DLL复制到java目录。
一个有点可怕的实现,但它的工作原理。 :(我希望这篇文章可以像其他人那样为别人带来许多麻烦。