terl / lazysodium-java

A Java implementation of the Libsodium crypto library. For the lazy dev.
https://github.com/terl/lazysodium-java/wiki
Mozilla Public License 2.0
135 stars 48 forks source link

Lazysodium under windows #41

Closed vogt31337 closed 5 years ago

vogt31337 commented 5 years ago

Stumbled across a similar error as in Issue #34:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'c:\temp\libsodium\libsodium.dll':

Native library (win32-x86-64/c:\temp\libsodium\libsodium.dll) not found in resource path (...) at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:302) at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:455) at com.sun.jna.Native.register(Native.java:1716) at com.goterl.lazycode.lazysodium.utils.NativeUtils.loadLibraryFromJar(NativeUtils.java:109) at com.goterl.lazycode.lazysodium.SodiumJava.registerFromResources(SodiumJava.java:156) at com.goterl.lazycode.lazysodium.SodiumJava.(SodiumJava.java:21) at de.fhg.iwes.opsim.mcp.webserver.Activator.main(Activator.java:93) Suppressed: java.lang.UnsatisfiedLinkError: Module not found. at com.sun.jna.Native.open(Native Method) at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:191) ... 6 more Suppressed: java.lang.UnsatisfiedLinkError: Modul not found.

    at com.sun.jna.Native.open(Native Method)
    at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:204)
    ... 6 more
Suppressed: java.io.IOException: Native library (win32-x86-64/c:\temp\libsodium\libsodium.dll) not found in resource path (...)
    at com.sun.jna.Native.extractFromResourcePath(Native.java:1089)
    at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:276)
    ... 6 more

Windows: Running Win 7 x64

java -version: java version "1.8.0_181" Java(TM) SE Runtime Environment (build 1.8.0_181-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

In Issue #34 is written something about dependency problems and updating your os seems to help with unix, But unfortunately not with windows. Also FAQ doesn't help. Maybe you could provide some insight on how to fix this on windows? Which libraries to install / is lazysodium compiled against, etc.

Thx!

gurpreet- commented 5 years ago

Hi @vogt31337,

Thank you for your submission.

Let me give you some insight. Lazysodium works by first extracting the libsodium.dll from the JAR to a temporary location. Then lazysodium loads it from that location.

Could you please verify if the libsodium.dll file is present in the location c:\temp\libsodium\libsodium.dll?

I also see that it's trying to load from win32-x86-64/c:\temp\libsodium\libsodium.dll. Is the full file path win32-x86-64/c:\temp\libsodium\libsodium.dll or c:\temp\libsodium\libsodium.dll?

vogt31337 commented 5 years ago

Sorry for this late response...

The lib is found in this location, I copied it there.

vogt31337 commented 5 years ago

Got a tip, used dumpbin /dependents to analyze the lazysodium.dll and found a missing dependency to libgcc_s_seh-1.dll, which is from the MinGW project. If I include this lib I get the following error:

java.io.IOException: Failed to create temp directory c:\temp\libsodium
    at com.goterl.lazycode.lazysodium.utils.NativeUtils.createTempDirectory(NativeUtils.java:143)
    at com.goterl.lazycode.lazysodium.utils.NativeUtils.loadLibraryFromJar(NativeUtils.java:75)
    at com.goterl.lazycode.lazysodium.SodiumJava.registerFromResources(SodiumJava.java:156)
    at com.goterl.lazycode.lazysodium.SodiumJava.<init>(SodiumJava.java:21)
    at de.fhg.iwes.opsim.mcp.webserver.Activator.main(Activator.java:93)
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.goterl.lazycode.lazysodium.Sodium.sodium_init()I
    at com.goterl.lazycode.lazysodium.Sodium.sodium_init(Native Method)
    at com.goterl.lazycode.lazysodium.Sodium.onRegistered(Sodium.java:24)
    at com.goterl.lazycode.lazysodium.SodiumJava.<init>(SodiumJava.java:22)
    at de.fhg.iwes.opsim.mcp.webserver.Activator.main(Activator.java:93)

The first is due to the folder already existing, but the second one is more important, it can't call init().

vogt31337 commented 5 years ago

Just compiled my own version of lazysodium, using visual studio 2017: -Compiles: fine! -Running the test suite: ok! -Dependency graph looks different...

Same error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: com.goterl.lazycode.lazysodium.Sodium.sodium_init()I
    at com.goterl.lazycode.lazysodium.Sodium.sodium_init(Native Method)
    at com.goterl.lazycode.lazysodium.Sodium.onRegistered(Sodium.java:24)
    at com.goterl.lazycode.lazysodium.SodiumJava.<init>(SodiumJava.java:22)
    at de.fhg.iwes.opsim.mcp.webserver.Activator.main(Activator.java:93)
vogt31337 commented 5 years ago

The Problem arises possibly due to these dlls:

API-MS-WIN-CORE-WINRT-ERROR-L1-1-0.DLL API-MS-WIN-CORE-WINRT-L1-1-0.DLL API-MS-WIN-CORE-WINRT-ROBUFFER-L1-1-0.DLL API-MS-WIN-CORE-WINRT-STRING-L1-1-0.DLL

They are part of the new windows WINRT platform: Windows 7, 64 bit, DLL problems As of now I'm not sure how to solve this problem...

rfquintero commented 5 years ago

Not sure if this helps, but was running into the same issue using Raspbian Stretch:

Caused by: java.lang.UnsatisfiedLinkError: com.goterl.lazycode.lazysodium.Sodium.sodium_init()I
  at com.goterl.lazycode.lazysodium.Sodium.sodium_init(Native Method)
  at com.goterl.lazycode.lazysodium.Sodium.onRegistered(Sodium.java:24)
  at com.goterl.lazycode.lazysodium.SodiumJava.<init>(SodiumJava.java:34)

I had the native library loaded, and even checked that it was able to find the init method:

NativeLibrary library = NativeLibrary.getInstance("sodium", Collections.singletonMap(Library.OPTION_CLASSLOADER, SodiumJava.class.getClassLoader()));
Function function = library.getFunction("sodium_init");
function.invoke(new Object[] {});

That would run fine, and then everything would throw the same error once I invoked the SodiumJava initializer: new LazySodiumJava(new SodiumJava("sodium"));

Oddly enough, what seemed to work was binding everything directly to the Sodium class, and not the SodiumJava class:

Native.register(Sodium.class,"sodium");
return new LazySodiumJava(new SodiumJava("sodium"));

This runs fine, and I'm able to use everything as usual. Wondering if the issue is caused by the included native scrypt methods in the SodiumJava class?

For the record, using: OpenJDK 1.8.0_181, Client VM build 25.181.b13

gradle dependencies:

implementation "com.goterl.lazycode:lazysodium-java:3.5.2"
implementation "net.java.dev.jna:jna:5.2.0"

Installed libsodium23 and libsodium-dev from stretch-backports.

vogt31337 commented 5 years ago

I think I finally found the problem: On windows (maybe also linux?) the NativeUtils.java can't load the .dll if it's already in the temp folder (see first exception). This is due to a "bug" in java discussion on StackOverflow which hinders java on deleting not empty dirs. Which in turn triggers the first IOException and then doesn't load the dll at all, triggering the next exception.

I've made a pull request, which should fix this problem.

gurpreet- commented 5 years ago

Hi @vogt31337 and @rfquintero,

Thank you for your very detailed responses. Let me get a virtual box running and test what's happening. Will update very soon.

gurpreet- commented 5 years ago

Hey I've just updated Lazysodium to 3.6.0 which contains your fix @vogt31337. Please let me know if it works for you.

If the fix doesn't work for you @rfquintero, please don't hesitate to open another issue :)

vogt31337 commented 5 years ago

@gurpreet- seems to be working for my case. So I will close the issue @rfquintero if in doubt open a new issue.

Thx everybody :) :+1: