[
https://issues.apache.org/jira/browse/CXF-2828?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Daniel Kulp reassigned CXF-2828:
--------------------------------
Assignee: Daniel Kulp
> JSR 250 @Resource annotation on field does not work for proxied service
> implementations
> ---------------------------------------------------------------------------------------
>
> Key: CXF-2828
> URL: https://issues.apache.org/jira/browse/CXF-2828
> Project: CXF
> Issue Type: Bug
> Components: JAX-WS Runtime
> Affects Versions: 2.2.8
> Reporter: Oliver Geisser
> Assignee: Daniel Kulp
>
> h2. Description
> A JAX-WS service implementation class has a private {{WebServiceContext}}
> field which is annotated with the JSR-250 {...@resource}} annotation. It has
> also some annotation - for example {...@transactional}} - which will make
> Spring wrapping it with a proxy. See the following code for an example:
> {code:title=SomeServiceImpl.java|borderStyle=solid}
> @Transactional
> @WebService(endpointInterface = "com.example.ISomeService")
> public class SomeServiceImpl implements SomeService {
> @Resource
> private WebServiceContext context;
> ...
> {code}
> In the current release (2.2.8) this does not work and throws an
> {{IllegalArgumentException}}.
> BTW There is the workaround to annotate a setter method instead of annotating
> the field.
> h2. Background of the bug
> Because the Spring {{CommonAnnotationBeanPostProcessor}} which will normally
> handle JSR-250 annotations ignores {{WebServiceContext}} {...@ressource}}
> annotations (see the Javadoc of
> [{{CommonAnnotationBeanPostProcessor}}|http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.html#ignoreResourceType%28java.lang.String%29])
> there needs to be a special handling inside of CXF. This special handling
> happens in the
> {{org.apache.cxf.jaxws.JaxWsServerFactoryBean.injectResources(Object
> instance)}} method:
> {code:title=JaxWsServerFactoryBean.injectResources(Object
> instance)|borderStyle=solid}
> /**
> * inject resources into servant. The resources are injected
> * according to @Resource annotations. See JSR 250 for more
> * information.
> */
> /**
> * @param instance
> */
> protected void injectResources(Object instance) {
> if (instance != null) {
> ResourceManager resourceManager =
> getBus().getExtension(ResourceManager.class);
> List<ResourceResolver> resolvers =
> resourceManager.getResourceResolvers();
> resourceManager = new DefaultResourceManager(resolvers);
> resourceManager.addResourceResolver(new
> WebServiceContextResourceResolver());
> ResourceInjector injector = new ResourceInjector(resourceManager);
> if (Proxy.isProxyClass(instance.getClass()) && getServiceClass()
> != null) {
> injector.inject(instance, getServiceClass());
> injector.construct(instance, getServiceClass());
> } else {
> injector.inject(instance);
> injector.construct(instance);
> }
> }
> }
> {code}
> h2. Bug
> As you can see there is already a special case to detect a proxy
> ({{Proxy.isProxyClass()}}). The bug is that even in the case of a proxy the
> code tries to inject into the field of the proxy. But the proxy does not have
> the field and this gives an {{IllegalArgumentException}} inside of
> {{ResourceInjector.injectField(Field field, Object resource)}}.
> h2. Fix
> In the case of a proxied object find the "wrapped" (target) object and inject
> into this object. This is possible because the proxy will be a Spring proxy
> and Spring has a special Interface ({{Advised}}) which will allow to access
> the target object. See the following code:
> {code:title=JaxWsServerFactoryBean.injectResources(Object instance) -
> Fixed|borderStyle=solid}
> /**
> * inject resources into servant. The resources are injected
> * according to @Resource annotations. See JSR 250 for more
> * information.
> */
> /**
> * @param instance
> */
> protected void injectResources(Object instance) {
> if (instance != null) {
> ResourceManager resourceManager =
> getBus().getExtension(ResourceManager.class);
> List<ResourceResolver> resolvers =
> resourceManager.getResourceResolvers();
> resourceManager = new DefaultResourceManager(resolvers);
> resourceManager.addResourceResolver(new
> WebServiceContextResourceResolver());
> ResourceInjector injector = new ResourceInjector(resourceManager);
> if (Proxy.isProxyClass(instance.getClass()) && getServiceClass()
> != null) {
> // FIXED: find and inject into the proxy target
> Object proxyTarget =
> ((org.springframework.aop.framework.Advised)instance).getTargetSource().getTarget();
> injector.inject(proxyTarget, getServiceClass());
> injector.construct(instance, getServiceClass());
> } else {
> injector.inject(instance);
> injector.construct(instance);
> }
> }
> }
> {code}
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.