Loading Issues with Multiple Class Loaders
michaelahlers opened this issue · 5 comments
Particularly when working in hosted environments (like IDEs), where different class loaders may be used between one run and the next, developers will encounter errors like the following:
java.lang.UnsatisfiedLinkError: Native Library /private/var/folders/d1/3323g01s4bn3ntx1g_yzm_dc0000gn/T/1621396069368823549/nu/pattern/opencv/osx/x86_64/libopencv_java249.dylib already loaded in another classloader
at java.lang.ClassLoader.loadLibrary0(test.sc5011658132463706269.tmp:1891)
at java.lang.ClassLoader.loadLibrary(test.sc5011658132463706269.tmp:1843)
at java.lang.Runtime.loadLibrary0(test.sc5011658132463706269.tmp:866)
at java.lang.System.loadLibrary(test.sc5011658132463706269.tmp:1115)
at nu.pattern.OpenCV$Loader.loadLibrary(test.sc5011658132463706269.tmp:221)
at nu.pattern.OpenCV$Loader.access$100(test.sc5011658132463706269.tmp:156)
at nu.pattern.OpenCV.loadLibrary(test.sc5011658132463706269.tmp:153)
at #worksheet#.get$$instance$$res1(test.sc5011658132463706269.tmp:5)
at #worksheet#.#worksheet#(test.sc5011658132463706269.tmp:27)
See the JNI 1.2 specification.
If sys_paths
is not set to null
, and the library is loaded by absolute path, this problem goes away. Comments by Holger Hoffstätte on a similar topic suggest stale class loaders are not garbage collected—possibly due to the reflection hack.
Ultimately, there are no good solutions—only partial workarounds. There are now two loader methods on nu.pattern.OpenCV
. Both are now safe to call spuriously, and give developers a choice between adding the native binary to java.library.path
at runtime and giving “shared” access, or forcibly loading a different copy of the library (which is not blocked by guards against the static ClassLoader.loadedLibraryNames
collection).