cxf-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Daniel Kulp (JIRA)" <j...@apache.org>
Subject [jira] Resolved: (CXF-2828) JSR 250 @Resource annotation on field does not work for proxied service implementations
Date Thu, 27 May 2010 16:44:39 GMT

     [ https://issues.apache.org/jira/browse/CXF-2828?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Daniel Kulp resolved CXF-2828.
------------------------------

    Fix Version/s: 2.2.9
       Resolution: Fixed

> 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
>             Fix For: 2.2.9
>
>
> 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.


Mime
View raw message