Kristian Kraljić You may compare programming with poetry,
a harmonic script is a piece of creativity which will last forever.
- Kristian Kraljić

Java – Global (low level) Keyboard / Mouse Hook

by Kristian Kraljic, February 9, 2016

About five years ago I started this blog by picking up an idea of Johannes Schüth (Jotschi) about a global keyboard and mouse listener for Java. Today I am very happy to announce the next major version of the library now available on GitHub!

system-hook-logo

Keyboard and mouse events in Java only work, if the registered component is in focus. For example, in case a window looses its focus (e.g. when minimized), it stops receiving any more events. Through a low-level system-wide hook it’s possible to deliver those events regardless. You’ll find all sources of the latest release, as well as binary bundles / prepackaged Java archives (JAR) on the GitHub project page.

The old post describes all changes I did to the initial version by Johannes (Jotschi). For the new major release I again reworked nearly every part of the library, to make it more stable and versatile. Here is what I did:

  • Optimized the native library C code, fixed bugs and removed all parts requireing a C++ compiler in the first place.
  • Renamed the event classes and listener interfaces and prepended Global to avoid conflicts with existing (Swing) event listeners.
  • Added support for mouseWheel events to the GlobalMouseListener.
  • Again allowed negative "out of bounds" values for GlobalMouseEvents, to also track the mouse pointer off screen (e.g. on multi-monitor setups).
  • Improved the threading concept and implemented a native error handling. The GlobalKeyboardHook and GlobalMouseHook constructors will now throw a UnsatisfiedLinkError if the native libraries can not be loaded or a RuntimeException in case hooking fails.
  • All the code has been moved to GitHub and binaries are now beeing continuously built by AppVeyor. Feel free to contribute on GitHub!

(Again) Last but not least, please share your ideas and problems in the comments. I will try to enhance the Global Keyboard / Mouse Hook based on your feedback. For the next release let’s see if we can get Linux and / or Mac OSX support going.

202 Comments

  1. Adam says:

    Hi,

    I was looking for a long time for something already implemented, works like a charm, thank you for sharing! :)

    Remark: you might consider including the MouhseHook .h/.cpp files into the source bundle download as it seems you forgot it.

    Nice job!
    Adam

  2. Kristian Kraljic says:

    Hey Adam,

    thanks for your comment.

    You are absolutely right. I will add them to the bundle of the next release.

    Thanks again & regards,
    Kristian

  3. Timo says:

    Hi,
    i’m not very good at programming in java yet and i have a problem. I always get an error in “Thread-0”, it says something about an “UnsatisfiedLinkError” as u can see here: http://nopaste.info/0d87f74746_nl.html

    Thanks for help…

  4. Thomas says:

    Hi,

    Very nice project. However I have the problem described by Timo with the new version (0.2.1).

    Exception in thread “Thread-2” java.lang.UnsatisfiedLinkError: de.ksquared.system.mouse.MouseHook.registerHook(Lde/ksquared/system/mouse/GlobalMouseListener;)V
    at de.ksquared.system.mouse.MouseHook.registerHook(Native Method)
    at de.ksquared.system.mouse.PoolHook.run(MouseHook.java:50)

    I use the jar with the lib in it.

    Thanks for any help…

  5. Thomas says:

    Hi! I researched my previous post a little bit and I came up with the following – if I do:

    System.loadLibrary(“mousehook”);
    the error message is:
    Can’t find dependent libraries

    If I then see what’s missing in dependency walker – it signals that the following libraries are missing:
    GPSVC.DLL and
    IESHIMS.DLL

    Maybe this can help?

  6. Byron says:

    Hi, I’m trying to use these .dll files with my x64 JVM and they won’t load. Is it possible for you to post an x64 build? I have been trying for hours to get the Microsoft SDK to compile it, but there are some linker problems I don’t understand (LNK2019 errors). Until then, I will try running in a 32-bit JRE.

    Thanks for the great utility, hopefully I will be able to use it!

    Byron

  7. Lucas says:

    Hey, I am having the same UnsatisfiedLinkError as mentioned above (using the newest version 0.2.1). Please let me know if you come up with a fix for this… the code would be very useful if fixed.

    Thanks,

    Lucas

  8. Byron says:

    If anyone is interested, I did figure out those LNK2019 errors I mentioned last week. When compiling for x64, it is for some reason necessary to specify User32.lib to the linker. Even if this lib is in the search path, the linker won’t discover that the dependencies are defined there. So for the cl.exe command line, the “/LINK” directive must be followed by option “/DEFAULTLIB:User32.lib”. It seems bizarre to me, but anyway, it works.

  9. ammonite says:

    That is what i needed and it works!
    Thanks

  10. Frank says:

    I had the same UnsatisfiedLinkError error as the people above. To solve my problem I changed from a 64-bit java version to a 32-bit version.

  11. Jason says:

    I compiled the DLLs with VisualStudio 2010, and am running the example code in Java. Everything works for a few seconds, I get output messages on my console, but then it dies with the following error. Has anyone else experienced this?

    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    # Internal Error (safepoint.cpp:572), pid=11308, tid=11872
    # Error: Deadlock in safepoint code. Should have called back to the VM before blocking.
    #
    # JRE version: 6.0_22-b04
    # Java VM: Java HotSpot(TM) 64-Bit Server VM (17.1-b03 mixed mode windows-amd64 )
    # An error report file with more information is saved as:
    # E:\Workspaces\…\hs_err_pid11308.log
    [Too many errors, abort]
    NATIVE: DllMain – DLL_PROCESS_ATTACH.
    NATIVE: Java_de_ksquared_system_mouse_MouseHook_registerHook – Hooking started!
    NATIVE: Java_de_ksquared_system_mouse_MouseHook_registerHook – Hook successful

    Example unique snippets from hs_err_pid11308.log file (the first is repeated many times, the second just once, at the end)

    ————— T H R E A D —————

    Current thread (0x0000000006931000): JavaThread “Thread-1” daemon [_thread_in_native_trans, id=11872, stack(0x0000000007cf0000,0x0000000007df0000)]

    Stack: [0x0000000007cf0000,0x0000000007df0000]
    [error occurred during error reporting (null), id 0xe0000000]

    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    # Internal Error (safepoint.cpp:572), pid=11308, tid=11872
    # Error: Deadlock in safepoint code. Should have called back to the VM before blocking.
    #
    # JRE version: 6.0_22-b04
    # Java VM: Java HotSpot(TM) 64-Bit Server VM (17.1-b03 mixed mode windows-amd64 )
    # If you would like to submit a bug report, please visit:
    # http://java.sun.com/webapps/bugreport/crash.jsp
    #

    ————— T H R E A D —————

    Current thread (0x0000000006931000): JavaThread “Thread-1” daemon [_thread_in_native_trans, id=11872, stack(0x0000000007cf0000,0x0000000007df0000)]

    Stack: [0x0000000007cf0000,0x0000000007df0000]

  12. Benjaminva says:

    Thank you so so very much, I spent 10 hours trying to do this and could not even run the basic JNI netbeans demo. I’m running on a vista 32 and it works great :D