Исключение в классе OSGI на Феликсе - PullRequest
3 голосов
/ 28 апреля 2010

Я довольно новичок в 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

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

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

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

спасибо

Nico

1 Ответ

2 голосов
/ 28 апреля 2010

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

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

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

...