ComponentDefinitionException while getting a bean from blueprint container in Fuse ESB 7.1
Environment
Fuse Enterprise ESB 7.1
Issue
-
Assume there is a bean requiring declarative transaction handling and thus annotated with
<tx:transaction\>
element declared in the blueprint container. -
If caller would attempt to get an instance of the bean via:
blueprintContainer.getComponentInstance(${bean_component_id});
- The caller may get the following exception:
getComponentInstance threw exception: Unable to convert instance ${bean_component_id}
org.osgi.service.blueprint.container.ComponentDefinitionException: Unable to convert instance ${bean_component_id}
at org.apache.aries.blueprint.container.BlueprintRepository.convert(BlueprintRepository.java:138)
at org.apache.aries.blueprint.container.BlueprintRepository.create(BlueprintRepository.java:146)
at org.apache.aries.blueprint.container.BlueprintContainerImpl.getComponentInstance(BlueprintContainerImpl.java:727)
...
at java.lang.Thread.run(Thread.java:662)
Caused by: org.osgi.service.blueprint.container.ComponentDefinitionException: Unable to create proxy for bean ${bean_component_id} in bundle ${bundle_name}
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.container.BlueprintRepository.convert(BlueprintRepository.java:136)
... 69 more
Caused by: org.apache.aries.proxy.UnableToProxyException: The class ${bean_class_name} 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)
Resolution
Proposed resolution is a workaround.
-
Make sure your bean class is implementing business interface (let's denote it
Interface_1
from now on). If class is not implementing interface, then create newInterface_1
, factor out some class' methods into it and have class implement it. Callers must useInterface_1
to communicate with the bean instance and should not depend on class directly. -
Create a new proxy bean denoted as
BeanProxy_1
implementingInterface_1
, holding reference to target object ofInterface_1
and delegating all the interface level calls to the target. -
Modify
blueprint.xml
to introduce proxy bean, retain<tx:transaction\>
on original class, example is below:
<bean id="osgitest.provider.jbpm.api.interaction_impl" class="original_bean_class_name"
scope="prototype">
...
<tx:transaction method="...,...," value="Required"/>
</bean>
<bean id="osgitest.provider.jbpm.api.interaction" class="proxy_bean_class_name"
scope="prototype">
<property name="target" ref="osgitest.provider.jbpm.api.interaction_impl" />
</bean>
And then have callers to obtain proxy e.g. blueprintContainer.getComponentInstance("osgitest.provider.jbpm.api.interaction");
and work with it.
Root Cause
Apache Aries blueprint container may use JDK proxy mechanims to wrap-up original object with interceptor handling transactions semantics (e.g. if no ASM library found). JDK proxies cannot handle objects which do not implement any interfaces.
In addition to that, there is a bean wiring bug in Aries ENTESB-577
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.
Comments