PHẦN 1
Tôi đang phát triển một ứng dụng Java sẽ được phát hành dưới dạng một cái bình. Chương trình này phụ thuộc vào các thư viện bên ngoài C++ được gọi là JNI. Để tải chúng, tôi sử dụng phương pháp System.load
với đường dẫn tuyệt đối và hoạt động tốt.Java - Tải dll theo đường dẫn tương đối và ẩn chúng trong một cái bình
Tuy nhiên, tôi thực sự muốn "ẩn" chúng bên trong JAR, vì vậy tôi đã tạo một gói để thu thập chúng. Điều này buộc tôi phải tải một đường dẫn tương đối - đường dẫn gói. Bằng cách tiếp cận này, tôi cho phép người dùng chạy JAR trong bất kỳ thư mục nào, mà không phải lo lắng về việc liên kết các tệp DLL hoặc chán với một quá trình cài đặt trước đó.
này ném ngoại lệ dự kiến:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library
Làm thế nào tôi có thể làm việc này?
PHẦN 2
Cách tiếp cận của sao chép các file DLL vào một thư mục (giải thích dưới đây) chỉ hoạt động khi tôi chạy nó dưới môi trường thực. Chạy một JAR xuất khẩu, những chương trình DLL cũng được tạo nhưng tải một JNI ném ngoại lệ tiếp theo:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:56) Caused by: java.lang.UnsatisfiedLinkError: C:\Users\Supertreta\Desktop\nm files\temp\jniBin.dll: Can't find dependent libraries at java.lang.ClassLoader$NativeLibrary.load(Native Method)
tôi chạy phương pháp nạp này:
public static void loadBinaries(){
String os = System.getProperty("os.name").toLowerCase();
if(os.indexOf("win") >= 0){
ArrayList<String> bins = new ArrayList<String>(){{
add("/nm/metadata/bin/dependence1.dll");
add("/nm/metadata/bin/dependence2.dll");
add("/nm/metadata/bin/dependence3.dll");
add("/nm/metadata/bin/dependence4.dll");
add("/nm/metadata/bin/jniBin.dll");
}};
File f = null;
for(String bin : bins){
InputStream in = FileManager.class.getResourceAsStream(bin);
byte[] buffer = new byte[1024];
int read = -1;
try {
String[] temp = bin.split("/");
f = new File(TEMP_FOLDER, temp[temp.length-1]);
FileOutputStream fos = new FileOutputStream(f);
while((read = in.read(buffer)) != -1) {
fos.write(buffer, 0, read);
}
fos.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.load(f.getAbsolutePath());
}
}
Tôi nghĩ rằng đây có thể là một vấn đề đặc quyền truy cập , nhưng không biết cách giải quyết nó. Bạn nghĩ sao?
Tại sao bạn muốn ẩn chúng? –
Để cung cấp một bình sạch – supertreta