Я пытался сделать эту работу целый день, и это отвратительно, потому что я не вижу ничего плохого в моем коде.OSGi ServiceFactory возвращает непобедимый объект
Вот мои классы:
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, который запускает пучок предков
/* 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, однако, когда я получаю реализацию displayer из ServiceFactory, зарегистрированного в качестве службы, (DisplayerImplementation instanceof Displayer) возвращает false.
это может быть ошибка в реализации реализации, которую я использую? Я использую felix btw.
если у вас здесь, спасибо за чтение! и я действительно оценю его, если вы попытаетесь мне помочь. Хорошего дня! или ночь!
Я предполагаю, что интерфейс Displayer существует дважды. Если вы используете встроенный контейнер OSGi, я думаю, что интерфейс Displayer существует в одном из пакетов и в пути к классам приложения. Поэтому в комплекте используется интерфейс Displayer из другого пакета, в то время как приложение использует интерфейс Displayer из своего собственного пути к классам. Убедитесь, что интерфейс Displayer поступает только из пути к классам приложения, а не из любого пакета! –
Чтобы получить точную информацию о том, откуда появились интерфейсы Displayer, поместите следующую строку внутри той части, где вы используете услугу, и где вы предлагаете эту услугу: System.out.println (Displayer.class.getClassLoader()); –
в случае, если вы не читали, спасибо за ответ! ты был прав! –