我已经尝试了一整天,这让我很沮丧,因为我没有发现我的代码有任何问题。
以下是我的课程:
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();
}
}
下面是运行previos捆绑的嵌入式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 instanceofDisplayer(返回true,然而,当我从注册为服务的ServiceFactory中获得显示器实现时,(DisplayerImplementation instance of Displayer(会返回false。
这可能是我使用的框架实现中的一个错误吗?我用的是felix btw.
如果你来到这里,感谢你的阅读!如果你能帮我的话,我会非常感激的。祝你今天愉快!或者晚上!
这里有一个特殊情况,因为您希望从OSGi容器外部访问OSGi服务。这只能通过容器外部的API包来完成,因为您无法访问捆绑包中的包。
容器外部的类路径中已经有com.lincesoft.itemperator.displayer.api包。因此,您只需将此包添加到框架属性org.osgi.framework.system.packages.extra中。这样,容器就可以在osgi中发布api包。
正如Balazs所写的,您还应该确保您部署的某个捆绑包中没有api包。这样可以确保OSGi不会意外地选择错误的api包。