J'ai écrit un module qui définit un service:Deux instances de mon module de mise en œuvre de services Liferay
public interface TranslationService {
// a method.
}
... un module qui implémente le service:
@Component(
immediate = true,
configurationPid = "my.TranslationConfiguration"
)
public class TranslationServiceImpl implements TranslationService {
log.info("Constructor " + getClass().getName()
+ " " + System.identityHashCode(this));
@Activate
@Modified
protected void activate(Map<String, Object> properties) {
log.info("Configuring " + translationService.getClass().getName()
+ " " + System.identityHashCode(this));
configuration = ConfigurableUtil.createConfigurable(
TranslationConfiguration.class, properties);
}
// an implementation of the method.
}
avec son activateur de service:
public class ServiceActivator implements BundleActivator {
private ServiceRegistration registration;
@Override
public void start(BundleContext context) throws Exception {
registration = context.registerService(TranslationService.class.getName(), new TranslationServiceImpl(), null);
}
[...]
}
... et un module qui utilise le service: 01
@Component(
immediate = true,
configurationPid = [...]
service = Portlet.class
)
public class TranslationPortlet extends MVCPortlet {
@Reference(unbind = "-")
protected void setTranslationService(TranslationService translationService) {
log.info("Using " + translationService.getClass().getName()
+ " " + System.identityHashCode(translationService));
this.translationService = translationService;
}
private TranslationService translationService;
}
Log
Se connecter quand je commence (via Gogo Shell) les modules API et mise en œuvre:
Constructor my.TranslationServiceImpl 606817095
Service registered.
STARTED my.impl_1.0.0 [538]
Constructor my.TranslationServiceImpl 362465287
Configuring my.TranslationServiceImpl 362465287
Puis, quand je commence (via Gogo Shell), le module en utilisant:
STARTED my.app_1.0.0 [558]
Using my.TranslationServiceImpl 606817095
Question
Pourquoi deux instances sont-elles utilisées?
Comment faire pour que tous les modules utilisent la même instance de mon implémentation de service?
Détails
stacktraces des deux fois le constructeur de mise en œuvre est appelée:
my.TranslationServiceImpl.<init>(TranslationServiceImpl.java:56)
my.ServiceActivator.start(ServiceActivator.java:24)
org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:774)
org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:1)
java.security.AccessController.doPrivileged(Native Method)
org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:767)
org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:724)
org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:951)
org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:328)
org.eclipse.osgi.container.Module.doStart(Module.java:566)
org.eclipse.osgi.container.Module.start(Module.java:434)
org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:402)
org.apache.felix.gogo.command.Basic.start(Basic.java:729)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.apache.felix.gogo.runtime.Reflective.invoke(Reflective.java:137)
Puis:
my.TranslationServiceImpl.<init>(TranslationServiceImpl.java:56)
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:423)
java.lang.Class.newInstance(Class.java:442)
org.apache.felix.scr.impl.manager.SingleComponentManager.createImplementationObject(SingleComponentManager.java:236)
org.apache.felix.scr.impl.manager.SingleComponentManager.createComponent(SingleComponentManager.java:108)
org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:906)
org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:879)
org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:748)
org.apache.felix.scr.impl.manager.AbstractComponentManager.enableInternal(AbstractComponentManager.java:674)
org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:429)
org.apache.felix.scr.impl.manager.ConfigurableComponentHolder.enableComponents(ConfigurableComponentHolder.java:657)
org.apache.felix.scr.impl.BundleComponentActivator.initialEnable(BundleComponentActivator.java:341)
org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:403)
org.apache.felix.scr.impl.Activator.access$200(Activator.java:54)
org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:278)
org.apache.felix.utils.extender.AbstractExtender.createExtension(AbstractExtender.java:259)
org.apache.felix.utils.extender.AbstractExtender.modifiedBundle(AbstractExtender.java:232)
org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:482)
org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:1)
org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:232)
org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:444)
org.eclipse.osgi.internal.framework.BundleContextImpl.dispatchEvent(BundleContextImpl.java:905)
org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEventPrivileged(EquinoxEventPublisher.java:165)
org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:75)
org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:67)
org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor.publishModuleEvent(EquinoxContainerAdaptor.java:102)
org.eclipse.osgi.container.Module.publishEvent(Module.java:461)
org.eclipse.osgi.container.Module.start(Module.java:452)
org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:402)
org.apache.felix.gogo.command.Basic.start(Basic.java:729)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.apache.felix.gogo.runtime.Reflective.invoke(Reflective.java:137)
donc son semble que je ne devrais pas instancier la mise en œuvre dans l'activateur de service ? C'est comme cela que cela semble être fait en this tutorial cependant.
Cela semble impossible. Avez-vous déjà vu une ligne indiquant "Configurer my.TranslationServiceImpl 1451438505"? –
Pouvez-vous vérifier avec constructor-logging? –
@NeilBartlett: J'ai ajouté plus de détails, plus la journalisation du constructeur. J'ai aussi réalisé que mon activateur de service causait probablement le problème, mais je ne suis pas sûr de savoir comment le changer. Merci beaucoup! –