Исключение класса OSGI для felix

Я новичок в osgi и пытаюсь собрать функциональное доказательство концепции.

Настройка заключается в том, что мой общий API создается в пакете с творческим именем common-api.jar без активатора пакета, но он экспортирует все свои интерфейсы. в этой ситуации интерес представляет DatabaseService.java.

Затем у меня есть второй пакет под названием systemx-database-service. Это реализует интерфейс службы базы данных. это отлично работает, так как в активаторе пакета реализации я проверяю соединение с базой данных и выбираю некоторые произвольные значения. Я также регистрирую службу, которую я хочу сделать доступной для других пакетов, например так:

   context.registerService(DatabaseService.class.getName(), new SystemDatabaseServiceImpl(context), new Properties());

Основная идея заключается в том, что при поиске ссылки на службу базы данных вы получите реализацию SystemDatabaseService.

Когда я выполняю проверку службы, вывод:

-> inspect s c 69
System Database Service (69) provides services:
----------------------------------------------
objectClass = za.co.xxx.xxx.common.api.DatabaseService
service.id = 39

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

context.getService(context.getServiceReference(DatabaseService.class));

я должен вернуть экземпляр DatabaseService.class, но, увы, не повезло. просто кажется, что он не может найти службу. держись со мной здесь, моя история становится страннее.

полагая, что некуда идти, но я написал это чудовище:

 for (Bundle bundle : bundles) {
        if (bundle.getSymbolicName().equals("za.co.xxx.xxx.database-service")) {
            ServiceReference[] registeredServices = bundle.getRegisteredServices();
            for (ServiceReference ref : registeredServices) {
                DatabaseService service = (DatabaseService) context.getService(ref);
               // use service here. 
               }
            }
        }
    }

теперь я действительно вижу ссылку на службу, но получаю эту ошибку

java.lang.ClassCastException: za.co.xxx.xxx.database.service.impl.SystemDatabaseServiceImpl cannot be cast to za.co.xxx.xx.common.api.DatabaseService

что безумие, так как реализация явно реализует интерфейс!

Любая помощь будет оценена по достоинству. Пожалуйста, имейте в виду, что я очень новичок в мышлении osgi, поэтому весь мой подход здесь может быть ошибочным.

ой. если кому-то нужны манифесты, я могу их опубликовать. и я использую maven-bnd-plugin для сборки и выполнения на felix.

Благодарность

Нико


person Nico    schedule 28.04.2010    source источник


Ответы (1)


Пакет тестов должен разрешить тот же импорт интерфейса DatabaseService, что и SystemDatabaseServiceImpl. Если этого не происходит, то getServiceReference документирует, что он вернет значение null, даже если служба будет найдена. Находя пакет вручную и пытаясь найти сервис и приведение, вы показываете, почему getServiceReference ведет себя таким образом: если бы он возвращал произвольные сервисы, приведения Java завершились бы неудачей.

Я бы рекомендовал печатать DatabaseService.class.getClassLoader() как в пакете impl, так и в тестовом пакете, чтобы убедиться, что они являются одним и тем же пакетом. Если это не так, вам нужно настроить метаданные OSGi MANIFEST.MF, чтобы обеспечить согласованное представление класса интерфейса.

Например, включен ли интерфейс DatabaseService в пакеты test и impl? Если да, вам нужно переместить этот интерфейс либо в пакет impl (и Export-Package), либо в третий пакет интерфейса и Export-Package. Затем настройте другие пакеты на Import-Package.

person Brett Kail    schedule 28.04.2010
comment
Получение класса A не может быть приведено к классу A — это классическая проблема Java, когда задействовано несколько загрузчиков классов, а OSGi имеет загрузчик классов для каждого пакета. - person SteveD; 28.04.2010
comment
пятно на bkail. когда я запустил sysout для загрузчиков классов, я получил [69.0 = загрузчик классов для целевой службы 74.0 = загрузчик классов для этого класса]. common-api находится в отдельном пакете. означает ли это, что мне нужно исключить его из банок, которые я создаю для пакетов реализации и тестирования? - person Nico; 29.04.2010
comment
благодаря. исключил из всего общий апи и БАМ. работает как шарм - person Nico; 29.04.2010