Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dll dependency not being found #547

Open
dlif-v opened this issue Jul 5, 2024 · 4 comments
Open

Dll dependency not being found #547

dlif-v opened this issue Jul 5, 2024 · 4 comments

Comments

@dlif-v
Copy link

dlif-v commented Jul 5, 2024

Using IKVM 8.8.1 in a .NET 6.0 Windows Application, I have a jar that calls System.loadLibrary("ABC"); where ABC depends on XYZ and each dll is in its own directory (eg C:\abc\ABC.dll and C:\xyz\XYZ.dll) and both directories are in PATH (and appear as expected in java.library.path).
I get the following exception:

java.lang.UnsatisfiedLinkError: C:\abc\ABC.dll: Can't find dependent libraries
Exception thrown: 'java.lang.UnsatisfiedLinkError' in IKVM.Java.dll

If I use the jar in a java app then it loads both dlls fine.
If I copy both dlls to the exe's dir then it loads both dlls fine (but that's not right or practical).
If I DllImport any function from ABC and call the function in C# then it loads both dlls fine (but that is hacky, etc).
If I add System.loadLibrary("XYZ"); in the java first then it loads both dlls fine (but this is not a cross-platform solution since on Android XYZ is named something else so it will fail there).

Expected: loading a lib from java should work the same as it does in java (and the regular .net app)

@AliveDevil
Copy link
Collaborator

AliveDevil commented Jul 5, 2024

Probably dependency issue with VCRT.
Check ABC.dll and XYZ.dll with Dependencies for direct dependencies (i.e. msvcrt, vcruntime).

copy both dlls to the exe's dir then it loads both dlls fine

scratch what I wrote.

@wasabii
Copy link
Contributor

wasabii commented Jul 5, 2024

Would probably need more details on the specific DLL or something. There's actually not much in this process that IKVM is responsible for. We call LoadLibraryExW(wfilename, 0, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); and present the error back as an exception. Everything that LoadLibraryExW does is up to Windows itself. We have very little control over how it goes about locating dependencies.

One thing I can sort of imagine is that maybe it depends on something else that is different in a native Java. But I can't know that without seeing it.

@dlif-v
Copy link
Author

dlif-v commented Jul 5, 2024

Thanks for the hint. I traced this issue back to a commit last June switching from LoadLibrary (which works fine in my case) to LoadLibraryEx with LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, and then LOAD_LIBRARY_SEARCH_DEFAULT_DIRS was added later. Note the documentation for both options say "Directories in the standard search path are not searched" which is what's breaking things.

The commit mentions it's trying to fix loading libs from a given path so my suggestion would be to revert back to using the regular LoadLibrary and call AddDllDirectory at some point to add the extra given paths.

@wasabii
Copy link
Contributor

wasabii commented Jul 5, 2024

Ahhhhh. Okay, so, yeah, the PATH env is left out.

So we have a problem here. Because IKVM runs in process with .NET, and is loaded as an assembly, I'm a bit hesitent to change anything related to the process overall. For instance, by calling AddDllDirectory. That effects the search order of not just IKVM loaded JNI stuff, but also anything loaded by .NET (other P/Invoke calls) or other dlls, etc.

As to LoadLibrary: the reason I replaced it with LoadLibraryEx, is so dependent DLLs in the same folder as their parent are found. LoadLibrary doesn't allow this. But it was necessary because of the load order of some of the built in JVM DLLs (libiava, libjvm, etc). Since these load directly out of the executable path on a normal JVM (java.exe is located in the same dir as net.dll, etc), but in the .NET case, the process application path may differ (foo.exe using IKVM against a ikvm home dir located elsewhere).

So I need to come up with a better solution it seems. Something that makes the dependent search path for JDK DLLs work, regardless where the process is loaded form, but also doesn't override the user expectations that dependents can be on PATH.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants