Menu

#13 Use System.loadLibrary instead of System.load

v1.0 (example)
closed-fixed
nobody
None
5
2016-06-30
2016-06-30
Mikhail T.
No

The System.load call expects a precise path to the requested library, which gets uncomfortably system-dependent very quickly. By using System.loadLibrary instead you get more portable code and allow the user to control (such as by setting LD_LIBRARY_PATH), where the shared object is:

--- JXGrabKey/Java/test/jxgrabkey/JXGrabKeyTest.java    2010-02-28 10:11:49.000000000 -0500
+++ JXGrabKey/Java/test/jxgrabkey/JXGrabKeyTest.java    2016-06-30 02:51:50.285529000 -0400
@@ -16,5 +16,5 @@
     @BeforeClass
     public static void setUpClass() throws Exception {
-        System.load(new File("../C++/dist/Release/GNU-Linux-x86/libJXGrabKey.so").getCanonicalPath());
+        System.loadLibrary("JXGrabKey");
         JXGrabKey.setDebugOutput(true);
         JXGrabKey.getInstance();

Discussion

  • Edwin Stang

    Edwin Stang - 2016-06-30

    Since this is just a test class I would rather keep it to the hard coded path. When integrating the library into your own application, you have to anyway load the library in a way that suits you (which might be System.loadLibrary). For the test classes I want to ensure that exactly the version I build for testing is used instead of one I might have installed on the computer and resides in my LD_LIBRARY_PATH. Also in my IDE I would not like having to specify a LD_LIBRARY_PATH for this. If you want to improve this, you could write some code that tries to determine the correct environment and replaces "GNU-Linux-x86" and "libJXGrabKey.so" to different values depending on the environment (win32/win64/linux-x86/linux-x64/arm/...) so the test is more portable. Or introduce an environment/jvm parameter to substitute the path in the test case. Otherwise we should stick to adjusting the path in the file depending on which environment you are running.

     

    Last edit: Edwin Stang 2016-06-30
  • Mikhail T.

    Mikhail T. - 2016-06-30

    I found the patch necessary for the FreeBSD port of JXGrabKey to be able to perform testing after a build. I understand your point, though -- the patch may remain FreeBSD-specific.

     
  • Edwin Stang

    Edwin Stang - 2016-06-30

    If you build some code in the test that looks up the appropriate file via a file search in the release directory and it works on all platforms, we could include this in trunk. Otherwise I would prefer If you set this up as a freebsd patch in the port.

     
  • Edwin Stang

    Edwin Stang - 2016-06-30

    Also thanks for putting in the work to port this and making it up to date. :)

     
  • Mikhail T.

    Mikhail T. - 2016-06-30

    Well, you could add setting of LD_LIBRARY_PATH to your build.xml, but it does not seem like anybody other than you and myself ever bother with the testing anyway...

    BTW, how does the code in the actual JXGrabKey.jar find the native library? Or is that a pure-Java implementation?

    Also thanks for putting in the work to port this and making it up to date. :)

    Oh, I'm trying to port Sikuli to FreeBSD -- and it requires JXGrabKey :)

     

    Last edit: Mikhail T. 2016-06-30
  • Edwin Stang

    Edwin Stang - 2016-06-30

    JXGrabKey.jar relies on the native c++ code. But it does not load the native library itself, since it is up to the application which uses JXGabKey to define how and when it is loaded. JXGrabKey makes no assumption to the deployment and directory layout, so the application has to wire things via System.load/Syste.loadLibrary in order to prevent those UnsatisfiedLinkErrors from happening.

     
  • Edwin Stang

    Edwin Stang - 2016-06-30

    I have added a try/catch block to the load call which now uses loadLibrary as a fallback if the path is invalid. build.xml does not run any tests, I run the tests via IDE. See current trunk version.

     
  • Edwin Stang

    Edwin Stang - 2016-06-30
    • status: open --> closed-fixed
     

Log in to post a comment.