.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/, он будет распространяться на все войны.

У меня была эта проблема, и я решил ее:

Проблема:

Проблема связана с некоторыми конфигурациями вашего сервера приложений, которые вызывают создание более одного war или же ear файлы и, следовательно, он создает более одного развернутого файла. Эти развернутые файлы пытаются иметь параллельный доступ к вашей собственной библиотеке, которая загружается в статическом блоке.

Решение:

  1. Остановите свой сервер приложений и закройте IDEA
  2. Завершить все java процессы из диспетчера задач
  3. Перейдите по этому адресу вашего сервера приложений: jboss-eap-6.4.0\standalone\configuration и открыть standalone.xml файл
  4. в standalone.xml удалите все deployments тег (не волнуйтесь, когда вы перезапускаете сервер приложений, он вставляет этот тег
  5. Перейдите по этому адресу вашего сервера приложений:jboss-eap-6.4.0\standalone\deployments и удалите все развернутые файлы и war файлы. (Вы можете сделать резервную копию ваших военных файлов)
  6. Откройте IntelliJ Idea и перейдите к: Изменить конфигурацию JBOSS -> вкладка Развертывание
  7. Удалить текущее развертывание и добавить новое, которое должно бытьexploded

Скопируйте библиотеки DLL во временные файлы во временный каталог перед их загрузкой. Удалите файлы, когда вы закончите. Таким образом, вы можете быть уверены, что одна и та же DLL не будет загружена дважды.

Другие вопросы по тегам