2013-08-16 14 views
8

Utilizzo Opencv 2.4.5 con Java per un po 'di tempo per creare un'applicazione e vorrei ora distribuire l'app. La libreria viene caricata utilizzando quanto segue:Come confezionare opencv + java in un jar

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

che funziona correttamente. Tuttavia, durante l'esportazione, non funziona durante l'esecuzione dal vaso:

java -jar build1.jar 

Il file opencv_java245.jar è incluso come una libreria utente, con un file nativo (libopencv_java245.dylib) collegato ad esso. Quando eseguo il jar eseguibile generato da Eclipse, ottengo l'UnsatisfiedLinkError di seguito, nonostante la compilazione/esecuzione corretta di 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) 

Qualcuno sa un modo semplice di imballaggio OpenCV nel vaso?

Aggiornamento: ora ho esaurito tutto. Posso aggiungere la libreria al mio percorso di build (e non usare System.loadLibrary) e funziona in eclissi, ma non quando è pacchettizzata nel jar. Ho provato di tutto. Ho anche controllato il tipo di libreria dinamica che sto cercando di carico - è

Mach-O 64-bit x86_64 dynamically linked shared library 

che sembra che dovrebbe funzionare bene. Ho usato -D64 e -D32 per testare e ottenere lo stesso risultato con entrambi.

+1

possibile duplicato di [estratto e caricare DLL da JAR] (http://stackoverflow.com/questions/4764347/extract -e-load-dll-from-jar) –

+2

Non è possibile caricare una libreria nativa (o DLL) direttamente da un JAR. Vedi la Domanda collegata per come comportarsi con questo. –

+0

Grazie @StephenC Ho provato questo metodo e continuo a ottenere UnsatisfiedLinkError ma con un messaggio diverso (qualcosa come il tipo sconosciuto). – alistair

risposta

10

Come ha detto Steven C, era come in Extract and load DLL from JAR e anche in un bug report. Ero un po 'ignorante su come usare i dylibs e stavo cercando di essere coerente con uno OpenCV tutorial che usava una "libreria utente" per aggiungere un barattolo e quindi aggiungere il dylib nativo. Inoltre, per qualche motivo il caricamento delle risorse anche quando si utilizzava "/" stava caricando dalla directory src, non dalla directory root del mio progetto (come nel caso di un progetto di test che ho realizzato).

Per coloro che cercano di fare la stessa cosa, ecco qualche codice per aiutare:

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); 
    } 
+0

Cosa fare se il sistema operativo è Linux? –

+0

Sembra che Linux usi i file .so http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html – alistair