Java: loading shared libraries with dependencies

I am wrapping a shared library (written in C) using Java using JNA. The shared library is written internally, but this library uses functions from another external library, which again depends on another external library. So the situation is something like this:

ext1 <- ext2 <- internal

those. the internal uses the ext2 external library, which again uses the ext1 external library. I tried:

System.loadLibrary("ext1");
System.loadLibrary("ext2");
NativeLIbrary.loadLibrary("internal",xxx.class);  

This approach does not work with "UnresolvedException" when loading the "ext2" library; the linker complains about the characters that are really present in the ext1 library. So, is it semmes that the System.loadLibrary () function does not make the characters from "ext1" globally accessible? When using the stdlib dlopen () function as:

handle = dlopen( lib_name , RTLD_GLOBAL );

All characters found in @lib_name will be available for character resolution on subsequent loads; I guess I would like something similar for the java variation of System.loadLibrary ()?

Regards - Joakim Hove

+5
source share
4 answers

OK

In the end, I found an acceptable solution, but not without a significant amount of hoops. What i do is

  • JNA dlopen() (libdl.so).
  • dlopen(), JNA, "ext1" "ext2" RTLD_GLOBAL.

: -)

+2

, , , , . JNA NativeLibrary#getInstance(), Linux RTLD_GLOBAL dlopen() ( Windows ).

, Java native, System.load() ( Sysem.loadLibrary()) NativeLibrary#getInstance().

-, JNA: JNA-61

, JNA, Java-. , :

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);

, OCR Java Tesseract. Tesseract Leptonica, lept tesseract. (System.load() System.loadLibrary()) , jna.library.path java.library.path. , JNA -.

Linux, , , .

+2

There is one more solution for this. You can execute dlopen directly inside the JNI code, for example:

void loadLibrary() {
  if(handle == NULL) {
    handle = dlopen("libname.so", RTLD_LAZY | RTLD_GLOBAL);
    if (!handle) {
      fprintf(stderr, "%s\n", dlerror());
      exit(EXIT_FAILURE);
    }
  }
}

...
...

loadLibrary();

So you open the library with RTLD_GLOBAL.

You can find a detailed description here: http://www.owsiak.org/?p=3640

+1
source

Try this, add this function to your code. Call it before loading your dlls. Use the location of your DLLs for the parameter.


    public boolean addDllLocationToPath(String dllLocation)
    {
        try
        {
            System.setProperty("java.library.path", System.getProperty("java.library.path") + ";" + dllLocation);
            Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
            fieldSysPath.setAccessible(true);
            fieldSysPath.set(null, null);
        }
        catch (Exception e)
        {
            System.err.println("Could not modify path");
            return false;
        }
        return true;
    }
}

0
source

All Articles