【问题标题】:Injecting transaction in OSGi reference listener with blueprint使用蓝图在 OSGi 引用侦听器中注入事务
【发布时间】:2013-07-09 12:52:01
【问题描述】:

我有一个 OSGi 包,它有一个参考侦听器类,用于跟踪其他 OSGi 包注册的服务。我已经使用蓝图配置了参考侦听器,并在 Felix 中部署了所有必要的 Aries 包:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0" xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0">  
    <reference-list id="ServiceList" interface="com.test.MyService" availability="optional">
        <reference-listener bind-method="bind" unbind-method="unbind">
            <bean class="com.test.MyServiceMonitor" />
        </reference-listener>
    </reference-list>
</blueprint>

在这个配置下一切都很好,MyServiceMonitor 类的绑定和取消绑定方法在服务来来去去时被调用。作为下一步,我希望绑定方法也可以在数据库中写入一些数据,因此我尝试在 MyServiceMonitor 中注入一个实体管理器,并通过如下更改 bean 标记来创建事务:

<bean class="com.test.MyServiceMonitor">
    <tx:transaction method="bind" value="RequiresNew" />
    <jpa:context property="entityManager" unitname="myunit" />
</bean>

当我启动捆绑包时,这种为绑定方法创建事务的尝试会导致以下异常。当我删除 tx:transaction 标记时,捆绑启动没有问题,而我已经能够在具有相同蓝图配置的其他(非引用侦听器)bean 中使用实体管理器和事务。

对于 OSGi 来说相对较新,我无法弄清楚这是否是预期的行为,如果是的话,在引用侦听器中执行数据库操作的正确方法是什么。对此有何见解?

2013-07-11 12:40:12,592 | ERROR | 20 - org.apache.aries.blueprint - 1.1.0 | org.apache.aries.blueprint.container.BlueprintContainerImpl | Unable to start blueprint container for bundle com.test.my-bundle
org.osgi.service.blueprint.container.ComponentDefinitionException: Unable to convert value BeanRecipe[name='#recipe-2'] to type class java.lang.Object
    at org.apache.aries.blueprint.di.CollectionRecipe.internalCreate(CollectionRecipe.java:92)
    at org.apache.aries.blueprint.di.AbstractRecipe.create(AbstractRecipe.java:106)
    at org.apache.aries.blueprint.container.AbstractServiceReferenceRecipe.createListeners(AbstractServiceReferenceRecipe.java:246)
    at org.apache.aries.blueprint.container.ReferenceListRecipe.internalCreate(ReferenceListRecipe.java:74)
    at org.apache.aries.blueprint.di.AbstractRecipe$1.call(AbstractRecipe.java:79)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at org.apache.aries.blueprint.di.AbstractRecipe.create(AbstractRecipe.java:88)
    at org.apache.aries.blueprint.container.BlueprintRepository.createInstances(BlueprintRepository.java:245)
    at org.apache.aries.blueprint.container.BlueprintRepository.createAll(BlueprintRepository.java:183)
    at org.apache.aries.blueprint.container.BlueprintContainerImpl.instantiateEagerComponents(BlueprintContainerImpl.java:668)
    at org.apache.aries.blueprint.container.BlueprintContainerImpl.doRun(BlueprintContainerImpl.java:370)
    at org.apache.aries.blueprint.container.BlueprintContainerImpl.run(BlueprintContainerImpl.java:261)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at org.apache.aries.blueprint.container.ExecutorServiceWrapper.run(ExecutorServiceWrapper.java:106)
    at org.apache.aries.blueprint.utils.threading.impl.DiscardableRunnable.run(DiscardableRunnable.java:48)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: org.osgi.service.blueprint.container.ComponentDefinitionException: Error setting property: PropertyDescriptor <name: listener, getter: null, setter: [class org.apache.aries.blueprint.container.AbstractServiceReferenceRecipe$Listener.setListener(class java.lang.Object)]
    at org.apache.aries.blueprint.container.BeanRecipe.setProperty(BeanRecipe.java:941)
    at org.apache.aries.blueprint.container.BeanRecipe.setProperties(BeanRecipe.java:907)
    at org.apache.aries.blueprint.container.BeanRecipe.setProperties(BeanRecipe.java:888)
    at org.apache.aries.blueprint.container.BeanRecipe.internalCreate2(BeanRecipe.java:820)
    at org.apache.aries.blueprint.container.BeanRecipe.internalCreate(BeanRecipe.java:787)
    at org.apache.aries.blueprint.di.AbstractRecipe.create(AbstractRecipe.java:106)
    at org.apache.aries.blueprint.di.CollectionRecipe.internalCreate(CollectionRecipe.java:90)
    ... 25 more
Caused by: org.osgi.service.blueprint.container.ComponentDefinitionException: Unable to create proxy for bean #recipe-3 in bundle com.test.my-bundle version 1.0.0.SNAPSHOT
    at org.apache.aries.blueprint.container.BeanRecipe.addInterceptors(BeanRecipe.java:771)
    at org.apache.aries.blueprint.container.BeanRecipe.wrap(BeanRecipe.java:841)
    at org.apache.aries.blueprint.container.AggregateConverter.convert(AggregateConverter.java:149)
    at org.apache.aries.blueprint.container.BlueprintRepository.convert(BlueprintRepository.java:402)
    at org.apache.aries.blueprint.utils.ReflectionUtils$PropertyDescriptor.convert(ReflectionUtils.java:394)
    at org.apache.aries.blueprint.utils.ReflectionUtils$MethodPropertyDescriptor.internalSet(ReflectionUtils.java:628)
    at org.apache.aries.blueprint.utils.ReflectionUtils$PropertyDescriptor.set(ReflectionUtils.java:378)
    at org.apache.aries.blueprint.container.BeanRecipe.setProperty(BeanRecipe.java:939)
    ... 31 more
Caused by: org.apache.aries.proxy.UnableToProxyException: The class com.test.MyServiceMonitor is not an interface and therefore a proxy cannot be generated.
    at org.apache.aries.proxy.impl.JdkProxyManager.getInterfaces(JdkProxyManager.java:43)
    at org.apache.aries.proxy.impl.JdkProxyManager.createNewProxy(JdkProxyManager.java:36)
    at org.apache.aries.proxy.impl.AbstractProxyManager.createDelegatingInterceptingProxy(AbstractProxyManager.java:75)
    at org.apache.aries.proxy.impl.AbstractProxyManager.createInterceptingProxy(AbstractProxyManager.java:53)
    at org.apache.aries.blueprint.container.BeanRecipe.addInterceptors(BeanRecipe.java:767)
    ... 38 more

【问题讨论】:

  • MyServiceMonitor 是否实现接口?
  • @SheenaArtrip 不,它不需要,因为参考侦听器不需要工作。

标签: osgi blueprint-osgi aries


【解决方案1】:

您的事务管理器正在使用 JdkProxyManager 来代理事务。内置的 JDK 代理管理器需要一个接口才能进行代理。最好的办法是用所需的方法创建一个接口并实现它。另一种选择是切换到基于 ASM、CGLib 或 JavaAssist 的 ProxyManager。

【讨论】:

  • 我尝试创建一个接口,该接口定义了我想要进行事务处理的方法并让 MyServiceMonitor 类实现此接口,但我仍然遇到相同的异常。我什至尝试将其作为服务公开(理想情况下我不想这样做),但仍然没有运气。也许我在蓝图配置中遗漏了什么?
猜你喜欢
  • 2014-02-06
  • 2013-05-24
  • 2013-07-31
  • 2013-06-05
  • 1970-01-01
  • 1970-01-01
  • 2013-09-21
  • 2016-12-04
  • 1970-01-01
相关资源
最近更新 更多