Java: load shared libraries with dependencies

前端 未结 6 1840
别那么骄傲
别那么骄傲 2021-02-14 16:43

I am wrapping a shared library (written in C) with Java using JNA. The shared library is written internally, but that library uses functions from another external library, which

6条回答
  •  暗喜
    暗喜 (楼主)
    2021-02-14 17:46

    It's an old question, but I've found an acceptable solution, which should also be portable, and I thought I should post an answer. The solution is to use JNA's NativeLibrary#getInstance(), because on Linux this will pass RTLD_GLOBAL to dlopen() (and on Windows this is not needed).

    Now, if you are using this library to implement a Java native method, you will also need to call System.load() (or Sysem.loadLibrary()) on the same library, after calling NativeLibrary#getInstance().

    First, a link to a JNA bug: JNA-61

    A comment in there says that basically one should load dependencies before the actual library to use from within JNA, not the standard Java way. I'll just copy-paste my code, it's a typical scenario:

    String libPath =
            "/path/to/my/lib:" + // My library file
            "/usr/local/lib:" +  // Libraries lept and tesseract
            System.getProperty("java.library.path");
    
    System.setProperty("jna.library.path", libPath);
    
    NativeLibrary.getInstance("lept");
    NativeLibrary.getInstance("tesseract");
    OcrTesseractInterf ocrInstance = (OcrTesseractInterf)
            Native.loadLibrary(OcrTesseractInterf.JNA_LIBRARY_NAME, OcrTesseractInterf.class);
    

    I've written a small library to provide OCR capability to my Java app using Tesseract. Tesseract dependes on Leptonica, so to use my library, I need to load libraries lept and tesseract first. Loading the libraries with the standard means (System.load() and System.loadLibrary()) doesn't do the trick, neither does setting properties jna.library.path or java.library.path. Obviously, JNA likes to load libraries its own way.

    This works for me in Linux, I guess if one sets the proper library path, this should work in other OSs as well.

提交回复
热议问题