Return-Path: Delivered-To: apmail-cxf-issues-archive@www.apache.org Received: (qmail 40007 invoked from network); 27 May 2010 16:45:00 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 27 May 2010 16:45:00 -0000 Received: (qmail 61616 invoked by uid 500); 27 May 2010 16:45:00 -0000 Delivered-To: apmail-cxf-issues-archive@cxf.apache.org Received: (qmail 61570 invoked by uid 500); 27 May 2010 16:45:00 -0000 Mailing-List: contact issues-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list issues@cxf.apache.org Received: (qmail 61562 invoked by uid 99); 27 May 2010 16:45:00 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 27 May 2010 16:45:00 +0000 X-ASF-Spam-Status: No, hits=-1472.7 required=10.0 tests=ALL_TRUSTED,AWL X-Spam-Check-By: apache.org Received: from [140.211.11.22] (HELO thor.apache.org) (140.211.11.22) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 27 May 2010 16:45:00 +0000 Received: from thor (localhost [127.0.0.1]) by thor.apache.org (8.13.8+Sun/8.13.8) with ESMTP id o4RGidx6027033 for ; Thu, 27 May 2010 16:44:39 GMT Message-ID: <2782670.27631274978679949.JavaMail.jira@thor> Date: Thu, 27 May 2010 12:44:39 -0400 (EDT) From: "Daniel Kulp (JIRA)" To: issues@cxf.apache.org Subject: [jira] Resolved: (CXF-2828) JSR 250 @Resource annotation on field does not work for proxied service implementations In-Reply-To: <2455737.18351274951136684.JavaMail.jira@thor> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 [ 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 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 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.