private boolean unpackLibrary ( String path ) { boolean retval = false ; try { final Enumeration < URL > c = JNILibrary . class . getClassLoader ( ) . getResources ( path ) ; while ( c . hasMoreElements ( ) ) { final URL url = c . nextElement ( ) ; log . trace ( "path: {}; url: {}" , path , url ) ; if ( url == null ) return false ; boolean unpacked = false ; File lib ; if ( url . getProtocol ( ) . toLowerCase ( ) . equals ( "file" ) ) { // it SHOULD already exist on the disk. let's look for it. try { lib = new File ( new URI ( url . toString ( ) ) ) ; } catch ( URISyntaxException e ) { lib = new File ( url . getPath ( ) ) ; } if ( ! lib . exists ( ) ) { log . error ( "Unpacked library not unpacked correctedly; url: {}" , url ) ; continue ; } } else if ( url . getProtocol ( ) . toLowerCase ( ) . equals ( "jar" ) ) { // sucktastic -- we cannot in a JVM load a shared library // directly from a JAR, so we need to unpack to a temp // directory and load from there. InputStream stream = url . openStream ( ) ; if ( stream == null ) { log . error ( "could not get stream for resource: {}" , url . getPath ( ) ) ; continue ; } FileOutputStream out = null ; try { File dir = getTmpDir ( ) ; // did you know windows REQUIRES .dll. Sigh. lib = File . createTempFile ( "humble" , JNIEnv . getEnv ( ) . getOSFamily ( ) == JNIEnv . OSFamily . WINDOWS ? ".dll" : null , dir ) ; lib . deleteOnExit ( ) ; out = new FileOutputStream ( lib ) ; int bytesRead = 0 ; final byte [ ] buffer = new byte [ 2048 ] ; while ( ( bytesRead = stream . read ( buffer , 0 , buffer . length ) ) > 0 ) { out . write ( buffer , 0 , bytesRead ) ; } unpacked = true ; } catch ( IOException e ) { log . error ( "could not create temp file: {}" , e ) ; continue ; } finally { try { stream . close ( ) ; } catch ( IOException e ) { } if ( out != null ) try { out . close ( ) ; } catch ( IOException e ) { } } try { doJNILoad ( lib . getAbsolutePath ( ) ) ; retval = true ; break ; } catch ( UnsatisfiedLinkError e ) { // expected in some cases, try the next case. } finally { if ( unpacked ) { // Well let's try to clean up after ourselves since // we had ot unpack. deleteUnpackedFile ( lib . getAbsolutePath ( ) ) ; } } } } } catch ( IOException e1 ) { retval = false ; } return retval ; }
Looks for a URL in a classpath and if found unpacks it