С PAX-CDI: Как определить метод производителя в одном комплекте и использовать его в другом комплекте?PAX-CDI: методы создания нескольких пакетов
Я предполагаю, что, поскольку в PAX-CDI межкомпонентные бин-инъекции должен использоваться служебный реестр OSGi, аннотация @OsgiServiceProvider также используется для методов производителя.
И так как для каждой точки впрыска требуется другой экземпляр, я думаю, мне нужен объем прототипа.
Так что я попытался (между прочим):
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
@Produces
@OsgiServiceProvider
@PrototypeScoped
public Logger getLogger(InjectionPoint injectionPoint) {
return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass());
}
И на стороне потребителя я попробовал:
@Inject
@OsgiService
private Logger logger;
Но это не работает.
Я получаю разные исключения в зависимости от среды исполнения.
Например. с Pax экзамена:
testParameterizedTypeSupported(org.ops4j.pax.cdi.test.InterBundleProducesTest) Time elapsed: 10.043 sec <<< ERROR!
org.ops4j.pax.swissbox.tracker.ServiceLookupException: gave up waiting for service org.slf4j.Logger
at org.ops4j.pax.swissbox.tracker.ServiceLookup.getService(ServiceLookup.java:199)
at org.ops4j.pax.swissbox.tracker.ServiceLookup.getService(ServiceLookup.java:136)
at org.ops4j.pax.exam.inject.internal.ServiceInjector.injectField(ServiceInjector.java:89)
at org.ops4j.pax.exam.inject.internal.ServiceInjector.injectDeclaredFields(ServiceInjector.java:69)
at org.ops4j.pax.exam.inject.internal.ServiceInjector.injectFields(ServiceInjector.java:61)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.createTest(ContainerTestRunner.java:61)
at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:68)
at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:37)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.invokeViaJUnit(JUnitProbeInvoker.java:124)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.findAndInvoke(JUnitProbeInvoker.java:97)
at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.call(JUnitProbeInvoker.java:73)
at org.ops4j.pax.exam.nat.internal.NativeTestContainer.call(NativeTestContainer.java:109)
at org.ops4j.pax.exam.spi.reactors.EagerSingleStagedReactor.invoke(EagerSingleStagedReactor.java:109)
at org.ops4j.pax.exam.junit.impl.ProbeRunner$2.evaluate(ProbeRunner.java:267)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.ops4j.pax.exam.junit.impl.ProbeRunner.run(ProbeRunner.java:98)
at org.ops4j.pax.exam.junit.PaxExam.run(PaxExam.java:93)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:283)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:173)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:128)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
И в моем окружении проекта я получаю, даже если у меня нет потребителя:
ERROR: org.ops4j.pax.cdi.extender (41): [CdiExtender(33)] The activate method has thrown an exception
org.ops4j.lang.Ops4jException: org.jboss.weld.exceptions.DefinitionException: WELD-001406: Cannot inject [BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedMethod] @Produces @OsgiServiceProvider @PrototypeScoped public somepackage.SomeClass.getLogger(InjectionPoint) in a non @Dependent scoped bean
at org.ops4j.pax.cdi.weld.impl.WeldCdiContainer.doStart(WeldCdiContainer.java:99)
at org.ops4j.pax.cdi.spi.AbstractCdiContainer.start(AbstractCdiContainer.java:89)
at org.ops4j.pax.cdi.extender.impl.CdiExtender.createContainer(CdiExtender.java:132)
at org.ops4j.pax.cdi.extender.impl.CdiExtender.addingBundle(CdiExtender.java:86)
at org.ops4j.pax.cdi.extender.impl.CdiExtender.addingBundle(CdiExtender.java:44)
at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:469)
at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:415)
at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:183)
at org.osgi.util.tracker.BundleTracker.open(BundleTracker.java:156)
at org.ops4j.pax.cdi.extender.impl.CdiExtender.activate(CdiExtender.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.felix.scr.impl.helper.BaseMethod.invokeMethod(BaseMethod.java:231)
at org.apache.felix.scr.impl.helper.BaseMethod.access$500(BaseMethod.java:39)
at org.apache.felix.scr.impl.helper.BaseMethod$Resolved.invoke(BaseMethod.java:624)
at org.apache.felix.scr.impl.helper.BaseMethod.invoke(BaseMethod.java:508)
at org.apache.felix.scr.impl.helper.ActivateMethod.invoke(ActivateMethod.java:149)
at org.apache.felix.scr.impl.manager.SingleComponentManager.createImplementationObject(SingleComponentManager.java:315)
at org.apache.felix.scr.impl.manager.SingleComponentManager.createComponent(SingleComponentManager.java:127)
at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:871)
at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:838)
at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:850)
at org.apache.felix.scr.impl.manager.DependencyManager$SingleStaticCustomizer.addedService(DependencyManager.java:931)
at org.apache.felix.scr.impl.manager.DependencyManager$SingleStaticCustomizer.addedService(DependencyManager.java:895)
at org.apache.felix.scr.impl.manager.ServiceTracker$Tracked.customizerAdded(ServiceTracker.java:1480)
at org.apache.felix.scr.impl.manager.ServiceTracker$Tracked.customizerAdded(ServiceTracker.java:1401)
at org.apache.felix.scr.impl.manager.ServiceTracker$AbstractTracked.trackAdding(ServiceTracker.java:1210)
at org.apache.felix.scr.impl.manager.ServiceTracker$AbstractTracked.track(ServiceTracker.java:1148)
at org.apache.felix.scr.impl.manager.ServiceTracker$Tracked.serviceChanged(ServiceTracker.java:1432)
at org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:987)
at org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:838)
at org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDispatcher.java:545)
at org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4547)
at org.apache.felix.framework.Felix.registerService(Felix.java:3521)
at org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:350)
at org.apache.felix.scr.impl.manager.AbstractComponentManager$3.register(AbstractComponentManager.java:1003)
at org.apache.felix.scr.impl.manager.AbstractComponentManager$3.register(AbstractComponentManager.java:992)
at org.apache.felix.scr.impl.manager.RegistrationManager.changeRegistration(RegistrationManager.java:134)
at org.apache.felix.scr.impl.manager.AbstractComponentManager.registerService(AbstractComponentManager.java:1044)
at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:841)
at org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:419)
at org.apache.felix.scr.impl.config.ConfigurableComponentHolder.enableComponents(ConfigurableComponentHolder.java:376)
at org.apache.felix.scr.impl.BundleComponentActivator.initialize(BundleComponentActivator.java:172)
at org.apache.felix.scr.impl.BundleComponentActivator.<init>(BundleComponentActivator.java:120)
at org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:258)
at org.apache.felix.scr.impl.Activator.access$000(Activator.java:45)
at org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:185)
at org.apache.felix.utils.extender.AbstractExtender.createExtension(AbstractExtender.java:259)
at org.apache.felix.utils.extender.AbstractExtender.modifiedBundle(AbstractExtender.java:232)
at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:479)
at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:414)
at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:232)
at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:443)
at org.apache.felix.framework.util.EventDispatcher.invokeBundleListenerCallback(EventDispatcher.java:913)
at org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:834)
at org.apache.felix.framework.util.EventDispatcher.fireBundleEvent(EventDispatcher.java:516)
at org.apache.felix.framework.Felix.fireBundleEvent(Felix.java:4531)
at org.apache.felix.framework.Felix.startBundle(Felix.java:2169)
at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1368)
at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:308)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.jboss.weld.exceptions.DefinitionException: WELD-001406: Cannot inject [BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedMethod] @Produces @OsgiServiceProvider @PrototypeScoped public somepackage.SomeClass.getLogger(InjectionPoint) in a non @Dependent scoped bean
at org.jboss.weld.bootstrap.Validator.validateMetadataInjectionPoint(Validator.java:327)
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:279)
at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:60)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:53)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
... 1 more
ERROR: org.ops4j.pax.cdi.extender (41): [CdiExtender(33)] Failed creating the component instance; see log for reason
AFAIK, это должно быть возможно с OSGi v6 с использованием PrototypeServiceFactory (https://osgi.org/javadoc/r6/core/org/osgi/framework/PrototypeServiceFactory.html). PAX-CDI поддерживает PrototypeServiceFactory с аннотацией @PrototypeScoped. – Puce
Я не представляю CDI только для входа в мои рамки, но как новую важную интегрированную функцию. Включение регистратора имеет преимущество уменьшения ошибок копирования и вставки. – Puce
В настоящее время я предполагаю, что это должно быть технически возможно с использованием PrototypeServiceFactory, но я думаю, что он еще не реализован. Я подал здесь эту проблему: https://ops4j1.jira.com/browse/PAXCDI-197 – Puce