java - PAX-CDI : inter bundle producer methods

标签 java osgi cdi

使用 PAX-CDI:如何在一个包中定义生产者方法并在另一个包中使用它?

我想因为在 PAX-CDI 中,捆绑 bean 间注入(inject)必须使用 OSGi 服务注册表,@OsgiServiceProvider 注释也用于生产者方法。

因为我想为每个注入(inject)点使用不同的实例,所以我想我需要原型(prototype)作用域。

所以我尝试了(除其他外):

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;

但它不起作用。

根据执行环境,我会收到不同的异常。

例如。与大同考试:

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

最佳答案

据我所知,不可能在包边界上使用@Produces。 您当然可以提供并注入(inject) OSGi 服务,但它不适用于您的情况。您希望为每个 bean 创建 Logger 并具有取决于 bean 类的不同记录器名称。这对于 OSGi 服务是不可能的。您创建一次服务并注入(inject)它。

对于记录您所做的全部努力并不是真正必要的。只需将 slf4j 工厂用作 OSGi 外部即可。它应该可以正常工作。

关于java - PAX-CDI : inter bundle producer methods,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31373428/

相关文章:

Java多线程文件读+操作+写

java - 无法使用 Apache POI 3.14 读取 XLSX 文件

eclipse - OSGi Felix 应用程序中未解析的 JavaFX 包

jpa - CDI 根据用户输入注入(inject) @PersistenceContext

java - 重写 ArrayList 添加方法时出现问题

java - android.intent.action.DOWNLOAD_COMPLETE 不会在下载失败时收到

java - 当 statusCode 断言失败并重新保证时打印响应正文

java - 如何修复 org.osgi.framework.BundleException : Unable to cache bundle?

java - 焊接-001408 : Unsatisfied dependencies for type Validator with qualifiers @Default

java - CDI多级注入(inject)?