Проблема, с которой вы сталкиваетесь, довольно существенная и основная. У вас есть статическое состояние в поддерживающей библиотеке CXF, но вы все еще хотите использовать совместно используемые экземпляры библиотек, использующих CXF. Вы не можете изменять общие библиотеки (из-за огромного размера), а также не можете изменять CXF (с закрытым исходным кодом?). Давайте назовем эти общие библиотеки Foo и Bar.
Предположим, у вас есть следующие классы:
CXF#1
Foo#1, using CXF#1
Bar#1, using CXF#1
WebApp#1, using Foo#1 and Bar#1
Если я правильно понимаю, теперь вы хотите, чтобы другое приложение использовало те же экземпляры Foo и Bar, без использования той же базовой библиотеки CXF # 1. Это соответствует следующей ситуации.
CXF#2
CXF#1
Foo#1, using CXF#1 when called by App#1, using CXF#2 when called by App#2
Bar#1, using CXF#1 when called by App#1, using CXF#2 when called by App#2
WebApp#1, using Foo#1 and Bar#1
WebApp#2, using Foo#1 and Bar#1
Это просто невозможно; не в OSGi и не в любой среде Java. Существующий класс не может динамически привязываться к другому классу, делая выбор на основе вызывающего пакета. Единственный способ сделать это без изменения библиотек - это дублировать вспомогательные библиотеки:
CXF#2
CXF#1
Foo#1, using CXF#1
Bar#1, using CXF#1
Foo#2, using CXF#2
Bar#2, using CXF#2
WebApp#1, using Foo#1 and Bar#1
WebApp#2, using Foo#2 and Bar#2
В самом деле, это много усилий и увеличит количество пакетов на диске и в памяти. Если пакет CXF может использоваться только одним приложением, наиболее логичным решением будет дублирование пакета и его внедрение везде, где вы его используете. Да, сюда входят все библиотеки, от которых зависит пакет.
Хакерский / рискованный способ решения этой проблемы заключается в следующем. Вы должны быть в состоянии декомпилировать класс CXF. Это позволит вам изменить класс следующим образом:
class CXF {
[...]
public static CXF getInstance() {
// based on the current Stack frame, determine which instance to return. Remember, the instance should be based on the WebApp bundle (while you still have shared libraries in between!)
}
}
Это не надежно. Предположим, что ваше WebApp запускает поток обратного вызова, происходящий из библиотеки A. Этот поток вызывает CXF.getInstance()
-> Метод getInstance()
не может определить, какой WebApp запустил поток обратного вызова.
Правильное решение - изменить все библиотеки, чтобы не использовать шаблон Singleton. Вероятно, вы можете решить проблему, внедрив специальный загрузчик классов, но это открывает еще одну банку с червями.
- РЕДАКТИРОВАТЬ -
После прочтения на CXF, кажется очень странным, что CXF представляет класс Singleton. Это сделано для OSGi! Возможно, вам лучше задать вопрос в списке рассылки CXF; они будут знать все о специальном сахаре и причинах создания одиночного экземпляра, и, возможно, уже подумали об этом сценарии использования.