kwhat / jnativehook

Global keyboard and mouse listeners for Java.
Other
1.73k stars 344 forks source link

Clarification needed: JNativeHook.x86_64.dll generated on app launch. #467

Closed Natarganiec closed 1 month ago

Natarganiec commented 1 month ago

hello :) I'm using the "JNativeHook" library in my Java application with Maven and the relevant dependency. Additionally, I employ the maven-assembly-plugin to bundle all libraries my app is using into a single JAR file. Afterward, I convert this JAR into an executable (.exe) using Launch4J.

JNativeHook is not the only external library my application uses, but it's the only one that extracts a DLL file (JNativeHook.x86_64.dll) to the same directory as my application upon launching the app.

My question is: Is it normal behavior for the JNativeHook.x86_64.dll file to be extracted to the application directory on startup? I want to ensure that this is expected and intended behavior or if there is a configuration I might be missing that could alter this outcome.

kwhat commented 1 month ago

Hi!

Is it normal behavior for the JNativeHook.x86_64.dll file to be extracted to the application directory on startup?

This is the default behavior, but not the recommended configuration for distribution. I originally extracted the appropriate library as a convenience for developers to get up and running with minimal configuration. This feature is likely going to go away because it has a lot of edge cases that lead to bug reports as developers don't have any insight into whats happening under the hood. Additionally, it may not be possible to dynamically load the libraries once this library starts supporting Wayland on Linux/Unix because there maybe more than one library for these platforms.

You probably want to extract all of the binaries from the jar and bundle the specific dll/so/dylib along side of the binary build you are distributing. I am not exactly sure how Launch4J handle JNI libraries. Normally, java has a property called java.library.path that points to the location where these libraries are suppose to live. For example, if you were calling this libraries jar, you should be doing something like java -jar JNativeHook.jar -Djava.library.path=C:\lib\ and the library will look for the JNativeHook.dll at that path location. Notice that the file name is different that what is in the jar. Ideally, you would only include the appropriate library for the platform you are using Launch4J to target. The java.library.path takes precedence over any automatic extraction, so if you specify it correctly the library will not attempt to do the extraction.

If you need to do custom library loading, there is an override mechanism poorly outlined in the doc/LibraryLoading.md file. Basically you can implement the com.github.kwhat.jnativehook.NativeLibraryLocator interface and then define the jnativehook.lib.locator property which would be set to your specific NativeLibraryLocator implementations fully-qualified class name. You can also override the name of the library using the jnativehook.lib.name property. The library name is the "JNativeHook" portion of the name and does not include the extension or the prefix. For example, libJNativeHook.so would still need the lib prefix and .so extension for Linux and Unix targets.

I am not sure how long the library locating mechanism will exist moving forward. I may remove it along with the library loading code in 3.0. There is still a lot up in the air with that release that is going to depend heavily on what we can implement on the libuiohook side of things regarding Wayland support. The code that powers the library loading lives in GlobalScreen.java and you are free to add your own implementation if I do decide to remove it from this library.

Let me know if you need any additional clarification.

Natarganiec commented 1 month ago

Thank you so much for the detailed explanation! I really appreciate the insights into the library extraction behavior and the recommendations for distribution. Your advice on extracting binaries and specifying library paths will be very helpful for configuring my application correctly.

Thanks again for going above and beyond in providing this information. Good luck with developing this awesome library! If I have any further questions or need additional clarification, I’ll definitely reach out.