0

我一整天都在努力完成这项工作,这令人沮丧,因为我没有看到我的代码有任何问题。

这是我的课程:

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();
    }
}

这是包含 DisplayerServiceFactory 的捆绑包的 Activator.java

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();
    }
}

这是运行 previus 包的嵌入式 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。

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

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

4

1 回答 1

1

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

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

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

于 2015-07-04T08:39:46.717 回答