пятница, 29 января 2010 г.

"Дружественные" бандлы или еще немного о расширении classpath в OSGi-приложениях


Продолжаем тему решения проблем с загрузкой классов в OSGi-приложениях. Рассмотрим такую ситуацию: у нас есть бандл A, где-то внутри которого используются классы из других бандлов. Причем, используются они по-разному, в том числе и производится загрузка этих классов по имени. Чтобы класс можно было загрузить, он должен присутствовать в classpath (подробнее про загрузку классов я писал в статье Пишем свой загручик java-классов). Classpath бандла формируется из двух частей: классы, присутствующие в самом бандле (задаются директивой Bundle-ClassPath) и классы, импортируемые из других бандлов (задаются директивами Import-Package и Require-Bundle). Так вот, проблема такая: мы хотим расширять возможности бандла A с помощью других, которые предоставляют ему свои классы. По понятным причинам мы не можем каждый такой дополнительный бандл добавлять в Import-Package/Require-Bundle бандла A. Вопрос: как быть?

Кстати, вы уже поняли к чему я клоню? Именно так используется Hibernate: есть один бандл, который содержит внутри себя Hibernate и какие-то механизмы его инициализации, а другие бандлы этот Hibernate используют. Но! Чтобы использовать Hibernate, он должен иметь возможность загружать классы сущностей, используемые в мэпингах и HQL-запросах. Понятно, что не хочется добавлять каждый бандл, использующий Hibernate в манифест хибернейтовского бандла, т.к. это убивает всю идею. модульности.


К счастью, начиная с Equinox 3.3 появилось понятие т.н. "дружественных" бандлов. Суть в следующем: один бандл (тот самый, который должен иметь доступ к не импортируемым им классам) позволяет с собой "дружить". Для этого в его манифест необходимо добавить параметр Eclipse-BuddyPolicy: registered. Другие бандлы, которые хотят разрешить ему доступ к своим классам, регистрируются как его друзья. Для этого в их манифест добавляется параметр Eclipse-RegisterBuddy: имя бандла-друга, например Eclipse-RegisterBuddy: name.samolisov.hibernate.

При этом следует учитывать, что "бандлы-друзья" получают доступ КО ВСЕМ классам, а не только к экспортируемым и что "дружба" работает в одну сторону.

Прикладываю пример: бандл name.samolisov.classpath.demo.service загружает классы, определенные в бандле name.samolisov.classpath.demo.client, хотя и не импортирует их.

Подробнее про работу с Hibernate в OSGi поговорим в следующей статье. Основная идея думаю понятна, а вот детали следует обсудить.

Скачать примеры к статье (исходники. Rar, 12 Кб)

Понравилось сообщение - подпишитесь на блог или читайте меня в twitter

2 комментария:

Василий Писпанен комментирует...

Добрый день. Если исходники примера ещё живы, перезалейте пожалуйста

Pavel Samolisov комментирует...

Здравствуйте, исходники к сожалению R.I.P.

Отправить комментарий

Любой Ваш комментарий важен для меня, однако, помните, что действует предмодерация. Давайте уважать друг друга!