Use System.loadLibrary instead of System.load
Brought to you by:
subes
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();
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
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.
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.
Also thanks for putting in the work to port this and making it up to date. :)
Well, you could add setting of
LD_LIBRARY_PATH
to yourbuild.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?Oh, I'm trying to port Sikuli to FreeBSD -- and it requires JXGrabKey :)
Last edit: Mikhail T. 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.
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.