9

I've been using Opencv 2.4.5 with Java for a while building an application and would now like to distribute the app. The library is loaded using the following:

static{ 
        System.loadLibrary("opencv_java245"); 
    }

which works fine. However, when exporting, it doesn't work when running from the jar:

java -jar build1.jar 

The opencv_java245.jar file is included as a user library, with a native file (libopencv_java245.dylib) connected to it. When running the executable jar generated from Eclipse, I get the UnsatisfiedLinkError below, despite things compiling/running fine in eclipse.

Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java245 in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1860)
    at java.lang.Runtime.loadLibrary0(Runtime.java:845)
    at java.lang.System.loadLibrary(System.java:1084)
    at com.drawbridge.Main.<clinit>(Main.java:12)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:266)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:56)

Anyone know a simple way of packaging OpenCV in the jar?

Update: I have now exhausted everything. I can add the library to my build path (and not use System.loadLibrary) and that works in eclipse, but not when packaged in the jar. I've tried everything. I also checked the type of dynamic library I'm trying to load - it's

Mach-O 64-bit x86_64 dynamically linked shared library

which seems like it should work fine. I've used -D64 and -D32 to test and get the same result with both.

6
  • 1
    possible duplicate of Extract and load DLL from JAR Commented Aug 16, 2013 at 9:26
  • 2
    You can't load a native library (or DLL) directly from a JAR. See the linked Question for how to deal with this. Commented Aug 16, 2013 at 9:27
  • Thanks @StephenC I've tried this method and still get UnsatisfiedLinkError but with a different message (something like unknown type). Commented Sep 12, 2013 at 17:22
  • What is the full message? Commented Sep 13, 2013 at 0:23
  • No Problem, sorted it :) Commented Sep 13, 2013 at 7:18

1 Answer 1

11

As Steven C said, it was as in Extract and load DLL from JAR and also in a bug report. I was slightly ignorant of how to use dylibs and was trying to be consistent with an OpenCV tutorial which used a "user library" to add a jar, and then add the native dylib. Also, for some reason loading resources even when using "/" was loading from the src directory, not my project's root directory (which was the case in a test project I made).

For those trying to do the same thing, here's some code to help:

private static void loadLibrary() {
    try {
        InputStream in = null;
        File fileOut = null;
        String osName = System.getProperty("os.name");
        Utils.out.println(Main.class, osName);
        if(osName.startsWith("Windows")){
            int bitness = Integer.parseInt(System.getProperty("sun.arch.data.model"));
            if(bitness == 32){
                Utils.out.println(Main.class, "32 bit detected");
                in = Main.class.getResourceAsStream("/opencv/x86/opencv_java245.dll");
                fileOut = File.createTempFile("lib", ".dll");
            }
            else if (bitness == 64){
                Utils.out.println(Main.class, "64 bit detected");
                in = Main.class.getResourceAsStream("/opencv/x64/opencv_java245.dll");
                fileOut = File.createTempFile("lib", ".dll");
            }
            else{
                Utils.out.println(Main.class, "Unknown bit detected - trying with 32 bit");
                in = Main.class.getResourceAsStream("/opencv/x86/opencv_java245.dll");
                fileOut = File.createTempFile("lib", ".dll");
            }
        }
        else if(osName.equals("Mac OS X")){
            in = Main.class.getResourceAsStream("/opencv/mac/libopencv_java245.dylib");
            fileOut = File.createTempFile("lib", ".dylib");
        }


        OutputStream out = FileUtils.openOutputStream(fileOut);
        IOUtils.copy(in, out);
        in.close();
        out.close();
        System.load(fileOut.toString());
    } catch (Exception e) {
        throw new RuntimeException("Failed to load opencv native library", e);
    }
Sign up to request clarification or add additional context in comments.

2 Comments

What to do if the Operating System is Linux?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.