.dll уже загружен в другой загрузчик классов?
У меня есть веб-приложение, работающее под Tomcat 3.2.1, которое должно выполнять вызовы JNI для доступа к данным и методам в унаследованном коде C++. Сервлет загружается при запуске веб-приложения, которое, как часть его init
метод, вызывает набор данных, специфичный для этого экземпляра веб-приложения, для загрузки в структуры данных C++.
Этот код Java для этого сервлета содержит следующее:
static
{
try {
System.loadLibrary("JCoreImpl");
System.out.println("JCoreImpl loaded");
m_bLibraryLoaded = true;
} catch (UnsatisfiedLinkError e) {
m_bLibraryLoaded = false;
System.out.println("JCoreImpl NOT loaded " + e);
}
}
Все работает хорошо, если есть только одно веб-приложение (назовем его "webapps/aaa").
Если у меня есть второе webapps ("webapps/bbb"), идентичное webapps / aaa, за исключением набора данных, используемого в структурах данных C++, то webapps / aaa запускается нормально, но когда запускается webapps / bbb, я получаю ошибка о том, что:
JCoreImpl NOT loaded java.lang.UnsatisfiedLinkError: Native Library
E:\WebStation\binDebug\JCoreImpl.dll already loaded in another classloader
Мне нужно иметь отдельный экземпляр нативной библиотеки для каждого из моих веб-приложений, поскольку каждый экземпляр должен содержать данные, уникальные для этого конкретного веб-приложения. Я просмотрел почтовые архивы и прочитал электронные письма Крейга Макланахана, объясняющие иерархию загрузчиков классов. Но я не смог найти ничего конкретного для загрузки уникального экземпляра нативной библиотеки для каждого веб-приложения.
4 ответа
Вы не можете загрузить одну и ту же нативную библиотеку дважды.
Поместите класс в файл JAR под <tomcat>/lib/
, он будет распространяться на все войны.
Смотрите раздел, в котором я сталкиваюсь с проблемами загрузчика классов при использовании JNI под Tomcat в вики Tomcat HowTo ( http://wiki.apache.org/tomcat/HowTo)
У меня была эта проблема, и я решил ее:
Проблема:
Проблема связана с некоторыми конфигурациями вашего сервера приложений, которые вызывают создание более одного war
или же ear
файлы и, следовательно, он создает более одного развернутого файла. Эти развернутые файлы пытаются иметь параллельный доступ к вашей собственной библиотеке, которая загружается в статическом блоке.
Решение:
- Остановите свой сервер приложений и закройте IDEA
- Завершить все
java
процессы из диспетчера задач - Перейдите по этому адресу вашего сервера приложений:
jboss-eap-6.4.0\standalone\configuration
и открытьstandalone.xml
файл - в
standalone.xml
удалите всеdeployments
тег (не волнуйтесь, когда вы перезапускаете сервер приложений, он вставляет этот тег - Перейдите по этому адресу вашего сервера приложений:
jboss-eap-6.4.0\standalone\deployments
и удалите все развернутые файлы иwar
файлы. (Вы можете сделать резервную копию ваших военных файлов) - Откройте IntelliJ Idea и перейдите к: Изменить конфигурацию JBOSS -> вкладка Развертывание
- Удалить текущее развертывание и добавить новое, которое должно быть
exploded
Скопируйте библиотеки DLL во временные файлы во временный каталог перед их загрузкой. Удалите файлы, когда вы закончите. Таким образом, вы можете быть уверены, что одна и та же DLL не будет загружена дважды.