OSGi ServiceFactory returns 一个不可转换的对象

OSGi ServiceFactory returns an uncasteable Object

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

这是我的 classes:

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

的包
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 容器的部分代码,运行是 previus 包

/* 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 class (DisplayerImplementation instanceof Displayer) returns 是的,但是,当我从注册为服务的 ServiceFactory 获得显示器实现时,(DisplayerImplementation instanceof Displayer) returns false.

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

如果你到了这里,感谢你的阅读!如果你愿意帮助我,我会非常感激。祝你今天过得愉快!或者晚上!

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

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

如 Balazs 所写,您还应确保您部署的其中一个捆绑包中没有 api 包。这确保 OSGi 不会意外选择错误的 api 包。