I have Java call a C++/CLR library through JNA. When attached to a C# DLL (using #using<myC#lib.dll>) the C# DLL MUST be in System32, nothing else will do, otherwise the JVM crashes (for obvious reasons).
#
# 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-开发者_JAVA百科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.
#
Sounds like a path problem, right? Well here is where it gets funny:
This works:
C:> set PATH=C:\Program Files\Java\jre6\bin;C:\workspace\bin\plugins\64;c:\Windows\System32
This doesn't:
C:> set PATH=C:\Program Files\Java\jre6\bin;C:\workspace\bin\plugins\64
Yes, the library resides in c:\workspace\bin\plugins\64
Notice that if system32 is included in path, it finds my library, so it's properly digging PATH directories (or so it seems), however if I drop it directly where my DLL is in my workspace it fails to run it. I doubt this is due to it being a .NET DLL (registering it to the GAC doesn't fix it, though if it did I cannot), and I have a feeling it's just a plain library look-up issue.
Am I missing something that Java may be doing to my library search paths? I can't guarantee I have the ability to write to System32 (not to mention I need to do some automated stuff and would like to stay FAR away from OS directories).
Edit 1:
This wont work if my C# DLL isn't in c:\Windows\System32, but is instead in C:\workspace\bin\plugins\64, so taking my dumb assumption I could gut System32 out of the equation.
C:> set PATH=C:\Program Files\Java\jre6\bin;C:\workspace\bin\plugins\64;c:\Windows\System32
Moving the DLL back to c:\windows\system32 allows it to work.
Edit 2:
If it makes any difference, it wont run at all if it's being run from Eclipse instead of the command line... System.getenv("PATH") being run from Eclipse shows my full path, dropping the C# DLL from the C++/CLR DLL allows it to run.
So it's entirely the .NET DLL, running Java from the command line the .NET DLL must be in System32, and will not run in Eclipse at all.
If you drop the .NET DLL from the C++/CLR DLL, it can run anywhere anytime.
Edit 3:
Seems to work fine when registered with the GAC (time to feel bad, I swear it wasn't working before), and related to this issue:
Calling .NET assembly from Java: JVM crashes
Now to see if I can get AssemblyResolve to work on the C++/CLR, which is exceedingly difficult due to the fact that it's a library.
Your .Net library obviously has dependencies. The one dependency I certainly expect is mscoree.dll, and that's located in System32. I'd also double-check whether there are CPU restrictions in either your DLL or any of its dependencies (seeing the "64-Bit Server").
Alright, registering with the GAC fixed it, so I wrote a very simple program that registers DLLs with the GAC (gacutil.exe is not redistributable).
I'll include this with the Java application, it can register the libraries at runtime.
Edit
I am unable to use the GAC (I plug into non-GAC registered libraries from here, and why deal with complicated dynamic binding), so I used the Assembly Binder Log Entry Viewer to show me where it was searching for the libraries, I've packaged the JRE with my application, so I can easily copy the .NET DLLs to the java directory at runtime.
A somewhat terrible implementation, but it works. :( I hope this post saves someone else as many headaches as I had.
精彩评论