java - OSGi ServiceFactory 返回一个不可转换的对象

标签 java osgi apache-felix service-factory embedded-osgi

我一整天都在努力让这项工作正常进行,这很令人沮丧,因为我没有发现我的代码有任何问题。

这是我的类(class):

DisplayerServiceFactory.java

package com.lincesoft.imperator.displayer.provider;

import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceRegistration;

import com.lincesoft.imperator.displayer.api.Displayer;

public class DisplayerServiceFactory implements ServiceFactory<Displayer> {

    public static final String NAME = "displayer_service_factory";

    @Override
    public void ungetService(Bundle bundle, ServiceRegistration<Displayer> registration, Displayer service) {
        // TODO Auto-generated method stub
    }
    @Override
    public Displayer getService(Bundle bundle, ServiceRegistration<Displayer> registration) {
        return new DisplayerImplementation();
    }
}

这是我的 Activator.java,用于包含 DisplayerServiceFactory 的 bundle

package com.lincesoft.imperator.displayer.launcher;

import java.util.Hashtable;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceRegistration;

import com.lincesoft.imperator.displayer.api.Displayer;
import com.lincesoft.imperator.displayer.provider.DisplayerServiceFactory;

public class Activator implements BundleActivator {

    private ServiceRegistration<?> DisplayerFactoryRegistration;

    @Override
    public void start(BundleContext bundle_context) throws Exception {
        System.out.println("Starting the Displayer Provider Bundle");
        ServiceFactory<Displayer> displayer_service_factory = new DisplayerServiceFactory();
        Hashtable<String,String> properties = new Hashtable<String,String>();
        properties.put("service.vendor", DisplayerServiceFactory.NAME);
        DisplayerFactoryRegistration = bundle_context.registerService(Displayer.class.getName(), displayer_service_factory,properties);
    }

    @Override
    public void stop(BundleContext context) throws Exception {
        System.out.println("Stopping the Displayer Provider Bundle");
        DisplayerFactoryRegistration.unregister();
    }
}

这是运行上一个包的嵌入式 osgi 容器的部分代码

/* Get a displayer instance from the service factory provided by the displayer provider bundle */
        ServiceReference<?>[] service_references = null;
        try {
            service_references = my_bundle_context.getServiceReferences(Displayer.class.getName(),"(service.vendor=displayer_service_factory)");
        } catch (InvalidSyntaxException e) {
            System.out.println("Sintaxis para obtener displayer_service_factory_reference invalida.");
            e.printStackTrace();
        }
        ServiceReference<?> displayer_service_factory_reference = null;
        if (service_references!=null && service_references.length==1) {
             displayer_service_factory_reference = service_references[0];
        } else {
            //Throw new NoDisplayerFactoryException();
        }
        Displayer bundle_displayer_instance = (Displayer) my_bundle_context.getService(displayer_service_factory_reference);

当我运行这段代码时,它给了我这个异常

Exception in thread "main" java.lang.ClassCastException: com.lincesoft.imperator.displayer.provider.DisplayerImplementation cannot be cast to com.lincesoft.imperator.displayer.api.Displayer
at com.lincesoft.imperator.procurator.launcher.Procurator.main(Procurator.java:94)

为什么会发生这种情况?很明显,DisplayerImplementation 是 Displayer 的一个实例。

此外,我还进行了一些调试,并且在 ServiceFactory 类 (DisplayerImplementation instanceof Displayer) 中返回 true,但是,当我从注册为服务的 ServiceFactory 获取显示器实现时,(DisplayerImplementation instanceof Displayer) 返回 false。

这可能是我正在使用的框架实现中的一个错误吗?顺便说一句,我正在使用 felix。

如果您看到这里,感谢您的阅读!如果您愿意帮助我,我将非常感激。祝你今天过得愉快!或夜晚!

最佳答案

这里有一个特殊情况,因为您想要从 OSGi 容器外部访问 OSGi 服务。这只能通过容器外部的 API 包来完成,因为您无法从 bundle 访问包。

您已经在容器外部的类路径中拥有 com.lincesoft.imperator.displayer.api 包。因此,您只需将此包添加到框架属性 org.osgi.framework.system.packages.extra 中即可。这样容器就将api包发布到了osgi内部。

就像 Balazs 所写的那样,您还应该确保您部署的 bundle 之一中没有 api 包。这可以确保 OSGi 不会意外选择错误的 api 包。

关于java - OSGi ServiceFactory 返回一个不可转换的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31218175/

相关文章:

java - OSGi-框架只会注册某些服务

java - OSGi 服务架构 : creation of service at request of consumer

java - Apache Felix Bundle 堆内存使用情况监控

java - 将 ArrayList 转换为数组

JAVA 将大文件拆分为多部分 ZIP。如何?

java - 在同一个 osgi 包中可以有两个服务接口(interface)吗?

android - 嵌入式 Felix,在 android-app 中运行无法解析 org.osgi.framework

java - 由于撇号,Hibernate 中的 QueryException

java - Broadleaf 或 apache Ofbiz

java - Apache felix 阻止了一个事件 - 如何删除它?