как работать с общими библиотеками для многих веб-приложений, использующих одни и те же библиотеки

У нас есть веб-приложение на Java, которое использует struts2, spring и JasperReport. Это приложение работает на glassfish 4.0.

библиотеки приложения находятся в папке WEB-INF/lib, а также в glassfish установлены на 4 больше, чем использует те же библиотеки.

Glassfish настроен на использование 1024mb для heapspace и 512m для permgen, и большая часть потребления памяти при использовании библиотек для каждого приложения находится в действиях struts и spring aop классы (с помощью профилировщика netbeans).

проблема, с которой мы сталкиваемся, - это объем памяти, потребляемый библиотеками в загрузчике классов для каждого приложения, потому что он высок и генерирует ошибки PermGen, и мы также заметили, что приложение работает медленнее с большим количеством пользователей.

из-за этого мы пытаемся использовать общие библиотеки, помещаем его в папку domain1/lib и обнаруживаем, что с одним развернутым приложением время загрузки и потребление памяти намного ниже, а приложение работает быстрее в целом. Но при развертывании остальных приложений на сервере хорошо работает только первое загруженное приложение, а остальные имеют ошибки при вызове действий struts2. Мы считаем, что это потому, что каждое приложение имеет несколько разные настройки на struts2 и log4j.

мы также пытались поставить только определенные библиотеки на glassfish и оставить только struts2 в приложении, но он показывает ошибки InvocationTargetException, потому что все библиотеки зависят от lib от apache-common, и не имеет значения, помещаем ли мы эти lib в то или иное место. Также, если мы поместим его в обоих местах, приложение не запустится.

  1. есть ли специальные настройки или рекомендации по использованию общих библиотек?
  2. есть ли способ использовать общие библиотеки, но загружать настройки для каждого приложения? или мы должны изменить настройки, чтобы сделать их все одинаковыми?

4 ответов


существуют ли какие-либо специальные настройки или рекомендации по использованию общих библиотек? Есть ли способ использовать общие библиотеки, но загружать настройки для каждого приложения? или мы должны изменить настройки, чтобы сделать их все одинаковыми?

это действительно интересные вопросы... Я не использую GlassFish, но,согласно документации :

Application-Specific Class Loading

[...] Можно указать классы библиотек для конкретных модулей или приложений [...] Используйте команду asadmin deploy с --libraries option и укажите пути, разделенные запятыми [...]

Обход Изоляции Загрузчика Класса

поскольку каждое приложение или индивидуально развернутый модуль class loader universe изолированы, приложение или модуль не может загружать классы из другого приложения или модуля. Это предотвращает два одноименных класса в разных приложениях или модулях от мешают друг другу.

чтобы обойти это ограничение для библиотек, классов утилит или индивидуально развернутых модулей, доступных более чем одному приложению, вы можете включить соответствующий путь к требуемым классам одним из следующих способов:

  • использование общего загрузчика классов
  • совместное использование библиотек в кластере
  • упаковка клиентской банки для одного приложения в другое приложение

использование общего загрузчика классов

чтобы использовать общий загрузчик классов, скопируйте файлы JAR в domain-dir/lib или


Я бы поспорил, что размещение библиотек под lib/ или lib/ext не решит ваши проблемы с производительностью. Вы ничего не писали о приложениях или настройках сервера, таких как размер приложения, доступная куча и пространство PermGen, но тем не менее я бы рекомендовал оставаться с отдельными библиотеками для каждого приложения.

Если вы разместите библиотеки в серверных dirs, они будут разделены между всеми приложениями. Вы потеряете возможность обновить только одно из ваших приложений до новой структуры или избавиться от нее любого из них. Ваше развертывание будет привязано к определенной серверной архитектуре.

и вы написали, что это не решает ваших проблем, это даже может вызвать новые.

Я бы рекомендовал инвестировать несколько часов в настройке сервера. Если он работает по умолчанию, выделите больше PermGen и HeapSpace.

Если это не помогает, вы должны глубоко проанализировать, что происходит не так. Общие библиотеки могут быть решением, но вы еще не знаете проблемы. IBM предлагает некоторые крутые и бесплатные инструменты для анализа дампов кучи, это может быть хорошей отправной точкой.


вы можете попытаться создать то, что известно как тощий войны. Упакуйте все свои войны внутри уха и переместите все общие банки из WEB-INF/lib до lib/ папка в ухе (не забудьте установить <library-directory> на application.xml).


Я пришел сюда в поисках руководства по установке библиотек, которые являются общими для нескольких приложений или проектов. Я глубоко разочарован, прочитав, что принятая практика способствует установке копии каждый общие библиотеки в каждого. Итак, если у вас есть десять веб-приложений, все из которых используют, e. г., httpcomponents-клиент, mysql-коннектор-java и т. д., то ваша установка содержит десять копий каждого.

это поведение напоминает мне, к сожалению, способ мышления, который побудил меня отказаться от мейнфрейма в пользу ПК; мышление, казалось, было "мне все равно, сколько ресурсов потребляет мое приложение. На самом деле, я хотел бы иметь возможность похвастаться тем, что это ресурс.- Извините, пожалуйста, меня тошнит.

  • интерфейс, предоставляемый библиотекой, является неизменяемым контрактом, который является не подлежит изменению по прихоти разработчика.

  • там эта концепция называется обратной совместимостью. Если вы сломаете его, вы создадите новый интерфейс.

Я знаю по крайней мере два типа интерфейсов, которые придерживаются буквы и духа этих правил.

  1. безусловно, самым старым является системные библиотеки IBM System/370. Вы могли бы Foo и Foo2, где последний продлевает и / или разрывает контракт, заключенный Foo интерфейс каким-то образом это сделал несовместимый.

  2. С самого начала в проекте Bell Labs Unix,стандартная библиотека времени выполнения C придерживался вышеуказанных правил.

  3. хотя он намного новее,спецификация интерфейса Microsoft COM применяет то же правило.

к их чести, Microsoft обычно придерживается этих правил в Win32 API тоже, хотя есть несколько исключений это API. В какой-то степени они пошли назад с .NET Framework, который, кажется, рабски следует по стопам среды Java, которую он так страстно стремится заменить.

Я использую библиотеки с 1978 года, и я понимаю, что цель ввода кода в библиотеку заключалась в том, чтобы сделать его многоразовым. При сохранении копий библиотечного кода в каждом приложении отпадает необходимость его повторной реализации для каждого нового проекта, что серьезно усложняет обновление, поскольку теперь у вас есть десять (или более) копий библиотеки, каждый из которых должен быть обновлен.

если библиотеки придерживаются правила, что интерфейс является неизменяемым контрактом, почему бы им не жить в shared каталог библиотеки, как и системные библиотеки Unix, которые живут в его /lib каталог, из которого все, что работает на хосте, имеет одну копию стандартной библиотеки времени выполнения C, Zlib и т. д.

цвет меня всерьез разочарованный.