Как исправить java.langUnsatisfiedLinkError в java-файле java? [Дубликат]

Еще несколько заметок.

  • Для отладки всегда завершайте функцию exec / shell_exec в var_dump() .
  • error_reporting(-1); следует как и display_errors, в качестве последнего средства даже set_error_handler("var_dump"); - если только посмотреть, не вызывает ли PHP сам execvp или еще.
  • Используйте 2>&1 (объединить оболочки STDERR в поток STDOUT), чтобы понять, почему вызов не выполняется. В некоторых случаях вам может потребоваться обернуть вашу команду в вызове дополнительной оболочки:
    // capture STDERR stream via standard shell
    shell_exec("/bin/sh -c 'ffmpeg -opts 2>&1' ");
    
    Повторно перенаправить файл журнала, как рекомендовано @Mike, является наиболее рекомендуемым подходом.
  • Альтернативный вариант между различными функциями exec для обнаружения сообщения об ошибках. Хотя они в основном делают то же самое, выходные пути возврата меняются: exec() → либо возвращает результат как результат функции, либо через необязательный параметр $output. Также предоставляет параметр $return_var, который содержит код errno / exit приложения запуска или оболочки. Вы можете получить: ENOENT (2) - Нет такого файла EIO (127) - Ошибка ввода-вывода: файл не найден shell_exec() → то, что вы хотите запускать в основном для выражений в стиле оболочки , Обязательно назначьте / напечатайте возвращаемое значение, например. var_dump(shell_exec("...")); `` встроенные backticks → идентичны shell_exec. system() → аналогичен exec, но всегда возвращает результат как результат функции (распечатайте!). Дополнительно позволяет фиксировать код результата. passthru() → еще одна альтернатива exec, но всегда отправляет любые результаты STDOUT в выходной буфер PHP. Какой из них делает его наиболее подходящей оболочкой exec. popen() или лучше proc_open() → позволяют индивидуально фиксировать STDOUT и STDERR.
  • Большинство ошибок оболочки заканчиваются на PHP или Apache error.log, когда они не перенаправлены. Проверьте свой журнал syslog или Apache, если ничего не дает полезных сообщений об ошибках.

Наиболее распространенными проблемами, возникающими у новичков PHP / LAMP, являются:

  • Как уже упоминалось @Kuf : для устаревших планов веб-хостинга вы все равно можете найти safe_mode или disable_functions. Ни одна из функций exec PHP не будет работать. (Лучше всего найти лучшего поставщика, иначе расследуйте «CGI», но не устанавливайте собственный интерпретатор PHP, пока не развернуты.)
  • Аналогично может быть AppArmor / SELinux / Firejail. Они ограничивают способность каждого приложения создавать новые процессы.
  • Предназначенный двоичный файл не существует. Практически не существует никаких веб-хостов, таких как ffmpeg. Вы не можете просто запускать произвольные команды оболочки без подготовки. Некоторые вещи необходимо установить!
    // Check if `ffmpeg` is actually there:
    var_dump(shell_exec("which ffmpeg"));
    
  • PATH выключен. Если вы установили специальные инструменты, вам необходимо убедиться, что они доступны. Использование var_dump(shell_exec("ffmpeg -opts")) будет искать все распространенные пути - или как было сказано / ограничено Apache (часто просто /bin:/usr/bin). Проверьте с помощью print_r($_SERVER);, что содержит ваш PATH, и если это покрывает инструмент, который вы хотите запустить. Кроме того, вам может потребоваться адаптировать настройки сервера (/ etc / apache2 / envvars) или использовать полные пути:
    // run with absolute paths to binary
    var_dump(shell_exec("/bin/sh -c '/usr/local/bin/ffmpeg -opts 2>&1'"));
    
    Это несколько подрывает концепцию оболочки. Лично я не считаю это предпочтительным. Однако это имеет смысл для целей безопасности; кроме того, для использования пользовательской установки, конечно.
  • Разрешения Для запуска двоичного кода в системе BSD / Linux его нужно сделать «исполняемым». Это то, что делает chmod a+x ffmpeg. Дальнейшее изменение пути к таким пользовательским двоичным файлам должно быть доступно для чтения пользователю Apache, с которым работают ваши скрипты PHP. Более современные настройки используют PHP, встроенные в режим FPM (suexec + FastCGI), где ваша учетная запись веб-хостинга равна тому, с чего работает PHP.
  • Тест с SSH. Это должно быть само собой разумеющимся, но перед запуском команд через PHP тестирование его в реальной оболочке было бы очень разумным. Зонд, например. ldd ffmpeg, если существуют все зависимости lib, и если он работает иначе.
  • Входные значения (GET, POST, имена FILE, пользовательские данные), которые передаются как аргументы команды в строках exec, должны быть экранированы с помощью escapeshellarg() .
    $q = "escapeshellarg";
    var_dump(shell_exec("echo {$q($_GET['text'])} | wc"));
    
    В противном случае вы легко получите синтаксические ошибки оболочки; и, вероятно, использовать код, установленный позже ...
  • Будьте внимательны, чтобы не комбинировать обратные ссылки с любой из функций *exec():
    $null = shell_exec(`wc file.txt`);
                       ↑           ↑
    
    Backticks запускает команду и оставляет shell_exec с выходом уже выполнил команду. Используйте обычные кавычки для обертывания параметра команды.

В Windows:

  • Вызовы CMD не будут хорошо воспроизводиться с потоками STDERR.
  • Определенно попробуйте сценарий Powershell для запуска любых приложений CLI или используйте командную строку, такую ​​как: system ("powershell -Command 'pandoc 2> & amp; 1'");
  • Используйте полные пути и предпочитайте передние косые черты всегда ("C:\Program Files\Whatevs\run.exe" с дополнительными кавычками, если пути содержат пробелы). Слишком быстро работающие чернила также работают в Windows с тех пор, как они были введены в MS-DOS 2.0
  • . Выясните , какая служба и учетная запись SAM выполняются как IIS / Apache, так и PHP. Убедитесь, что у него есть разрешения на выполнение.
  • Обычно вы не можете запускать приложения с графическим интерфейсом. (Типичное обходное решение - вызовы taskcheduler или WMI.)

59
задан YCF_L 30 April 2017 в 08:06
поделиться

12 ответов

Я уверен, что путь к классам и путь поиска разделяемой библиотеки имеют мало общего с друг другом. Согласно JNI Book (который, по общему признанию, старый), в Windows, если вы не используете системное свойство java.library.path, DLL должна находиться в текущем рабочем каталоге или в каталоге, указанном в Windows PATH.


Обновление:

Похоже, что Oracle удалил PDF со своего веб-сайта. Я обновил ссылку выше, чтобы указать на экземпляр PDF, который живет в Техасском университете в Арлингтоне.

Кроме того, вы также можете прочитать HTML-версию Oracle спецификации JNI , Это живет в разделе Java 8 веб-сайта Java и, надеюсь, будет некоторое время.


Обновление 2:

По крайней мере, в Java 8 (я не знаю, t проверены более ранние версии), вы можете сделать:

java -XshowSettings:properties -version

, чтобы найти путь поиска совместно используемой библиотеки. Посмотрите на значение свойства java.library.path в этом выходе.

33
ответ дан QuantumMechanic 15 August 2018 в 20:51
поделиться
  • 1
    Да, CLASSPATH вообще не используется. Я не уверен, что cwd используется вообще. java.library.path или просто PATH. @dB ', то место, где у вас есть, теперь wrong . – Ernest Friedman-Hill 23 May 2011 в 04:41
  • 2
    Большое спасибо, ребята! Я думаю, что часть проблемы здесь была путаницей с моей стороны между переменной среды Windows PATH, java.library.path и java CLASSPATH. Теперь все имеет смысл. – dB' 23 May 2011 в 07:26
  • 3
    Пожалуйста, объясните, как вы преодолели эту проблему? – SL_User 16 June 2012 в 12:48
  • 4
    @SL_User Я думаю, что если вы добавите каталог, где библиотеки относятся к переменной окружения «путь», и перезапустите командную строку или терминал, это должно исправить. Java ищет банки под classpath и библиотеки в пути. – xxjjnn 2 February 2013 в 19:40
  • 5
    Основываясь на этом ответе, похоже, что эта команда для обновления 2 доступна с по меньшей мере Java 7: stackoverflow.com/a/8472139/901641 – ArtOfWarfare 30 September 2016 в 15:59

В моей ситуации я пытался запустить веб-сервис java в Tomcat 7 через разъем в Eclipse. Приложение работает хорошо, когда я развернул файл войны на экземпляр Tomcat 7 на моем ноутбуке. Для приложения требуется драйвер jdbc типа 2 для «IBM DB2 9.5». По какой-то нечетной причине соединитель в Eclispe не мог видеть или использовать пути в переменных среды IBM DB2, чтобы добраться до DLL-файлов, установленных на моем ноутбуке, как клиент jcc. В сообщении об ошибке либо указано, что ему не удалось найти файл db2jcct2 dll, либо ему не удалось найти зависимые библиотеки для этого DLL-файла. В конечном итоге я удалил соединитель и перестроил его. Затем он работал правильно. Я добавляю это решение здесь как документацию, потому что мне не удалось найти это конкретное решение в другом месте.

1
ответ дан bwfrieds 15 August 2018 в 20:51
поделиться

Имели идентичную проблему с машиной XP при установке javacv и opencv в сочетании с Eclipse. Оказалось, что мне не хватало следующих файлов:

  • msvcp100.dll
  • msvcr100.dll

Как только они были установлены, проект скомпилирован и работает нормально.

9
ответ дан Community 15 August 2018 в 20:51
поделиться
  • 1
    У меня есть аналогичная проблема, которая исчезает после установки пакета «Распространяемый пакет Microsoft Visual C ++ 2010 SP1» (x86) & quot; – Kirill Mikhailov 18 April 2016 в 06:49

Если вы загружаете 32-разрядную версию вашей DLL с 64-разрядной JRE, у вас может возникнуть проблема. Это был мой случай.

3
ответ дан EFalco 15 August 2018 в 20:51
поделиться
  • 1
    Это, скорее всего, и мой случай; если кто-то знает об известных обходных решениях, которые мне были бы интересны; за исключением загрузки 64-битной версии, так как в этом случае процесс не является dll, а chromedriver.exe - драйвером Selenium для Chrome, который, насколько я могу судить, представлен только в 32-разрядной версии. – SantiBailors 16 December 2016 в 11:31

У меня была такая же проблема, и я пробовал все, что было опубликовано здесь, чтобы исправить это, но никто не работал для меня. В моем случае я использую Cygwin для компиляции dll. Кажется, что JVM пытается найти JRE DLL на виртуальном пути Cygwin. Я добавил путь виртуального каталога Cygwin к DLL JRE, и теперь он работает. Я сделал что-то вроде:

SET PATH = "/ cygdrive / c / Program Files / Java / jdk1.8.0_45";% PATH%

1
ответ дан estebanuri 15 August 2018 в 20:51
поделиться

Проверьте правильность пути к вашей библиотеке или нет. Конечно, вы можете использовать следующий код для проверки пути к пути к вашей библиотеке: System.out.println(System.getProperty("java.library.path"));

Вы можете назначить java.library.path при запуске приложения Java:

java -Djava.library.path=path ...
4
ответ дан hoat4 15 August 2018 в 20:51
поделиться

Я нашел отличную статью некоторых друзей в сейфе, которые прошли через то же самое, что и я. Это сработало для меня, поэтому, надеюсь, это поможет вам! Прочитайте, если вам интересно ( Опасности загрузки собственных библиотек на Android ) или просто используйте

compile 'com.getkeepsafe.relinker:relinker:1.2.3'

и замените

System.loadLibrary("myLibrary");

с

ReLinker.loadLibrary(context, "mylibrary");
1
ответ дан rhysl 15 August 2018 в 20:51
поделиться

Я хочу сообщить об этом интересном случае, попробовав весь вышеперечисленный метод, ошибка все еще существует. Странно, что это работает на компьютере под управлением Windows 7, но в Windows XP это не так. Затем я использую хост зависимостей и обнаружил, что в Windows XP нет VC ++ Runtime в качестве требования к моей DLL. После установки VC ++ Runtime package здесь он работает как шарм. Меня беспокоило то, что он продолжает говорить. Невозможно найти зависимые библиотеки, в то время как интуитивно зависит от JNI-зависимой dll, однако, наконец, получается, что зависимая от JNI dll требует другого зависимого dl. Надеюсь, это поможет.

15
ответ дан rushi 15 August 2018 в 20:51
поделиться
  • 1
    В этом случае сообщение корректно, хотя и вводит в заблуждение. В тестовом поле отсутствовали обе версии VC ++ и библиотека, скомпилированная в режиме отладки (в зависимости от non -redistributable debug runtimes). Dependency Walker очень помог понять это. – Johnny Baloney 21 September 2014 в 17:27
  • 2
  1. Перейдите в http://tess4j.sourceforge.net/usage.html и нажмите Visual C++ Redistributable for VS2012
  2. Загрузите его и запустите VSU_4\vcredist_x64.exe или VSU_4\vcredist_x84.exe в зависимости от конфигурации вашей системы
  3. Поместите файлы dll в папку lib вместе с вашими другими библиотеками (например, \lib\win32-x86\your dll files).
-2
ответ дан seinecle 15 August 2018 в 20:51
поделиться

У меня была точно такая же проблема, и, наконец, она была решена.

Я поместил все зависимые DLL в ту же папку, где был сохранен mylib.dll, и убедитесь, что JAVA Compiler смог его найти (если в пути компиляции нет mylib.dll, будет ошибка сообщая об этом во время компиляции). Важно отметить, что вы должны убедиться, что все зависимые библиотеки имеют одну и ту же версию с mylib.dll, например, если ваша версия mylib.dll является версией, тогда вы также должны поместить в нее версию всех зависимых библиотек ,

Надеюсь, это поможет другим, кто столкнулся с одной и той же проблемой.

1
ответ дан Steven Peng 15 August 2018 в 20:51
поделиться
  • Краткий ответ: для ошибки «не удается найти зависимую библиотеку» проверьте свой $ PATH (соответствует пункту № 3 маркировки ниже)
  • Длинный ответ: чистый мир java: jvm использует " Classpath ", чтобы найти файлы классов JNI world (java / native boundary): jvm использует« java.library.path »(который по умолчанию равен $ PATH), чтобы найти dlls чистый родной мир: собственный код использует $ PATH для загрузки других dlls
1
ответ дан user2038596 15 August 2018 в 20:51
поделиться
11
ответ дан Community 5 September 2018 в 20:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: