Java - Загрузка библиотек DLL по относительному пути и их скрытие в банке

ЧАСТЬ 1

Я разрабатываю приложение Java, которое должно быть выпущено как jar. Эта программа зависит от внешних библиотек C ++, вызываемых JNI. Чтобы загрузить их, я использую метод System.load с абсолютным путем, и он отлично работает.

Однако я действительно хочу «спрятать» их внутри JAR, поэтому я создал пакет для собрать их. Это заставляет меня загружать относительный путь - путь к пакету. При таком подходе я позволяю пользователю запускать JAR в любом каталоге, не беспокоясь о связывании библиотек DLL и не беспокоясь о предыдущем процессе установки.

Это вызывает ожидаемое исключение:

Исключение в потоке "main" java. lang.UnsatisfiedLinkError: Ожидается абсолютный путь к библиотеке

Как я могу заставить это работать?

ЧАСТЬ 2

Подход копирования DLL в папку (объясненный ниже) работает только тогда, когда я запускаю его в среде eclipse. При запуске экспортированного JAR двоичные файлы DLL создаются хорошо, но загрузка JNI вызывает следующее исключение:

Исключение в потоке «main» java.lang.reflect.InvocationTargetException

  в org.eclipse.jdt.internal.jarinjarloader .JarRsrcLoader.main (JarRsrcLoader.java:56)
 Вызвано: java.lang.UnsatisfiedLinkError: C: \ Users \ Supertreta \ Desktop \ nm files \ temp \ jniBin.dll: не удается найти зависимые библиотеки в java.lang.ClassLoader $ NativeLibrary.load (собственный метод)

Я использую этот метод загрузки:

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());
        }
    }

Я думаю, что это может быть проблема с правами доступа, но не знаю, как ее решить. Что вы думаете?

20
задан Raedwald 13 October 2016 в 15:42
поделиться