Как загрузить библиотеку из jar

Иногда возникает необходимость включить dll или so файл  в jar архив и поставить всё одним файлом. Но тут возникает проблема — java не умеет грузить библиотеки таким образом. В этом случае вам поможет решение ниже.

static {
	try {
		System.loadLibrary("opencv_java249");
	} catch (UnsatisfiedLinkError e) {
		try {
			NativeUtils.loadLibraryFromJar("/libopencv_java249.so");
		} catch (IOException e1) {
			throw new RuntimeException(e1);
		}
	}
}
public class NativeUtils {
    public static void loadLibraryFromJar(String path) throws IOException {
        if (!path.startsWith("/")) {
            throw new IllegalArgumentException("The path has to be absolute (start with '/').");
        }
 
        String[] parts = path.split("/");
        String filename = (parts.length > 1) ? parts[parts.length - 1] : null;
 
        String prefix = "";
        String suffix = null;
        if (filename != null) {
            parts = filename.split("\\.", 2);
            prefix = parts[0];
            suffix = (parts.length > 1) ? "."+parts[parts.length - 1] : null; 
        }
 
        if (filename == null || prefix.length() < 3) {
            throw new IllegalArgumentException("The filename has to be at least 3 characters long.");
        }
 
        File temp = File.createTempFile(prefix, suffix);
        temp.deleteOnExit();
 
        if (!temp.exists()) {
            throw new FileNotFoundException("File " + temp.getAbsolutePath() + " does not exist.");
        }
 
        byte[] buffer = new byte[1024];
        int readBytes;
 
        InputStream is = NativeUtils.class.getResourceAsStream(path);
        if (is == null) {
            throw new FileNotFoundException("File " + path + " was not found inside JAR.");
        }
 
        OutputStream os = new FileOutputStream(temp);
        try {
            while ((readBytes = is.read(buffer)) != -1) {
                os.write(buffer, 0, readBytes);
            }
        } finally {
            os.close();
            is.close();
        }
 
        System.load(temp.getAbsolutePath());
    }
}
  1. Пока что нет комментариев.
  1. Пока что нет уведомлений.