2011-05-20 4 views
5

Проблема: мое приложение использует две библиотеки, которые используют несовместимые версии третьей библиотеки. Кто-нибудь знает какой-либо метод изоляции классов?Как использовать два несовместимых класса с таким же полным именем?

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

Я также думаю о весне, но не знаю, обеспечивает ли она такую ​​изоляцию.

+0

Я полагаю, что эти два класса не находятся в отдельных пространствах имен? –

+0

Я не понимаю, что означает «пространство имен» в контексте Java. Имя пакета? Пусть они будут в разных пакетах, если это важно. – Nulldevice

+0

К сожалению, я имел в виду пакеты. А также, я неправильно понял ваш вопрос, поэтому я не думаю, что это актуально! –

ответ

1

если мы будем загружать одну версию класса, мы не можем загрузить другие - класс уже загружен?

Неверно. Погрузчик класса считается частью идентификатора класса. Если он загружен другим загрузчиком классов, он считается другим классом.

+0

Означает ли это, что мы можем обрабатывать классы как объекты Java? Например, внесите их в массив или список или создайте более одного экземпляра? – Nulldevice

+1

Классы @Nulldevice могут быть созданы только из байт-кода, по загрузчикам классов. Однако да, они являются объектами и могут быть помещены в массивы или списки. Я думаю, что только ClassLoaders должны будут делать такие вещи. –

2

ClassLoaders - это в основном элементы, которые придают смысл классам JVM. Они образуют иерархию, в которой корень лежит в JVM и загружает классы Java. ApplicationClassLoader - это первый ClassLoader, который вы должны учитывать, поскольку он загружает все классы вашего приложения.

Когда класс загружен, все его ссылки на другие классы разрешаются и классы классов тезисов загружаются. JVM по умолчанию предоставляет систему, в которой загрузчики классов сначала попросят своего родителя, чтобы они уже загрузили класс. Если нет, они ищут в своем пути к классам

Два класса могут быть изолированы, если они живут в двух разных загрузчиках классов, а не в загрузчике классов приложений. Это не сложно. Вам нужно только создать загрузчик классов (например, URLClassLoader), указав его родительский элемент и его путь к классу (место, где находится байт-код)

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

Это довольно хорошей изоляция

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

-1

Если хотя бы одна из библиотек является открытым исходным кодом, а библиотека, на которую они зависят, является открытым исходным кодом, не нужно возиться с загрузчиками классов. Просто переименуйте все пакеты в одной из версий библиотеки, на которую зависит, следя за тем, чтобы также изменить весь код, который относится к этим пакетам. Hey presto - нет именных столкновений. Это то, что Sun действительно делал для JDK, когда они включали Xerces и Xalan за кулисами.

+0

Что, если я скажу, что это проект, разработанный ~ 50 инженерами-программистами? Я не хочу отвечать за исправление ошибок тысяч строк кода. Не так просто менять версии некоторых библиотек, даже открытые источники. – Nulldevice

+0

Вы можете просто написать скрипт, который выполняет необходимые переименования, и запустить этот скрипт для каждой новой версии, выпущенной. Следите за «Class.forName», но это должно быть относительно просто. –

+0

Сэр, у него есть десятки тысяч строк кода - вы шутите? – Nulldevice

Смежные вопросы