When I searched for ways to load a JNI library from a jar there were numerous hints of how to do it, but no code that I could find. So here’s my solution:
import java.util.zip.ZipFile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
public abstract class UnixDomainSocket {
static {
try {
// get the class object for this class, and get the location of it
final Class c = UnixDomainSocket.class;
final URL location = c.getProtectionDomain().getCodeSource().getLocation();
// jars are just zip files, get the input stream for the lib
ZipFile zf = new ZipFile(location.getPath());
InputStream in = zf.getInputStream(zf.getEntry("libunixdomainsocket.jnilib"));
// create a temp file and an input stream for it
File f = File.createTempFile("JARLIB-", "-libunixdomainsocket.jnilib");
FileOutputStream out = new FileOutputStream(f);
// copy the lib to the temp file
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0)
out.write(buf, 0, len);
in.close();
out.close();
// load the lib specified by it’s absolute path and delete it
System.load(f.getAbsolutePath());
f.delete();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
// …
}
This particular example is for JUDS.
It could be extended to load one of several libraries for different architectures, .jnilib or .dylib for Mac OS X, .so for Linux, and .dll for Windows.
This seems like a lot of hoops to jump through, but I couldn’t find an easier way to do it. If you know of a better way, please let me know in the comments.