Integrating Spring 3 + GenericDAO (Don't repeat the DAO!) + CXF JAX-RS (JAXB Databinding) with a Generic Service Interface ---------------------------------------------------------------------------------------------------------------------------
Key: CXF-3022 URL: https://issues.apache.org/jira/browse/CXF-3022 Project: CXF Issue Type: Bug Components: JAXB Databinding Affects Versions: 2.2.10 Environment: Spring 3.03, CXF 2.2.10, Apache Tomcat 6.0.26... Reporter: Ivan Vitoria Priority: Blocker Hello everyone, I'm trying to use a generic interface implementation as a JAX-RS service in order to accomplish basic rest operations for all model data (in the same way that the pattern [GenericDAO|http://www.ibm.com/developerworks/java/library/j-genericdao.html]. The interface: {code:title=IRestService.java|borderStyle=solid} public interface IRestService<T, PK extends Long> { T getById(PK id); PK add(T instance); } {code} The generic service implementation: {code:title=GenericRestServiceImpl.java|borderStyle=solid} public class GenericRestServiceImpl<T, PK extends Long> implements IRestService<T, PK> { private IGenericDAO<T, PK> iDAO; public void setiDAO(IGenericDAO<T, PK> iDAO) { this.iDAO = iDAO; } public T getById(PK id) { return iDAO.read(id); } public PK add(T instance) { return iDAO.create(instance); } {code} The simple POJO I want to send and receive: {code:title=MobilityUser.java|borderStyle=solid} @XmlRootElement(name="MobilityUser") public class MobilityUser implements Serializable { private Long id; private String login; private String nif; public MobilityUser() { } // Setters & getters omitted... } {code} The most relevant section of Spring context configuration (applicationContext.xml): {code:xml} <!-- DAO Configuration (SessionFactory, DataSource, etc. omitted) --> <bean id="abstractDAO" class="org.springframework.aop.framework.ProxyFactoryBean" abstract="true" /> <bean id="abstractDaoTarget" class="com.ica.mobility.persistence.dao.genericdao.GenericDAOHibernate" abstract="true"> <property name="sessionFactory"> <ref bean="mobilitySessionFactory"/> </property> </bean> <bean id="userDAO" parent="abstractDAO"> <property name="proxyInterfaces"> <value>com.ica.mobility.persistence.dao.genericdao.IGenericDAO</value> </property> <property name="target"> <bean id="userBean" parent="abstractDaoTarget"> <constructor-arg> <value>com.ica.mobility.model.bean.MobilityUser</value> </constructor-arg> </bean> </property> </bean> <!-- CXF Configuration --> <jaxrs:server id="genericServer" modelRef="classpath:/WEB-INF/model/resources.xml" abstract="true"> <jaxrs:features> <cxf:logging/> </jaxrs:features> </jaxrs:server> <bean id="userServer" parent="genericServer"> <property name="address" value="/user" /> <property name="serviceBeans"> <bean id="userService" class="com.ica.mobility.mobile.service.GenericRestServiceImpl"> <property name="iDAO"> <ref bean="userDAO"></ref> </property> </bean> </property> </bean> {code} The JAX-RS model (resources.xml): {code:xml} <model xmlns="http://cxf.apache.org/jaxrs"> <resource name="com.ica.mobility.mobile.service.IRestService" path="/" consumesType="application/xml" producesType="application/xml"> <operation name="getById" verb="GET"> <param name="id" type="QUERY"/> </operation> <operation name="add" verb="POST" path="/add"> <param name="instance" type="REQUEST_BODY" /> </operation> </resource> </model> {code} There is no problem with GET operation (getById method). However, a runtime exception (NullPointerException) occurs when a POST request is performed. Server log with StackTrace: {code:title=server log|borderStyle=solid} 04-oct-2010 11:43:17 org.apache.cxf.interceptor.LoggingInInterceptor logging INFO: Inbound Message ---------------------------- ID: 3 Address: /MobilityServer/mobile/user/add Encoding: ISO-8859-1 Content-Type: application/xml Headers: {content-type=[application/xml], host=[localhost:8080], Content-Length=[90], user-agent=[Jakarta Commons-HttpClient/3.1], accept-encoding=[gzip,deflate], Content-Type=[application/xml]} Payload: <MobilityUser> <id>5</id> <login>Login</login> <nif>Nif</nif> </MobilityUser> -------------------------------------- Listening for transport dt_shmem at address: tomcat_shared_memory_id 04-oct-2010 11:46:52 org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging ADVERTENCIA: Interceptor for {http://service.mobile.mobility.ica.com/}IRestService has thrown exception, unwinding now java.lang.NullPointerException at java.lang.Class.isAssignableFrom(Native Method) at org.apache.cxf.jaxrs.utils.InjectionUtils.isSupportedCollectionOrArray(InjectionUtils.java:554) at org.apache.cxf.jaxrs.provider.JAXBElementProvider.isReadable(JAXBElementProvider.java:89) at org.apache.cxf.jaxrs.provider.ProviderFactory.matchesReaderCriterias(ProviderFactory.java:457) at org.apache.cxf.jaxrs.provider.ProviderFactory.chooseMessageReader(ProviderFactory.java:425) at org.apache.cxf.jaxrs.provider.ProviderFactory.createMessageBodyReader(ProviderFactory.java:269) at org.apache.cxf.jaxrs.provider.ProviderFactory.createMessageBodyReader(ProviderFactory.java:279) at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:960) at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:575) at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:540) at com.ica.mobility.util.CustomInInterceptor.processRequest(CustomInInterceptor.java:242) at com.ica.mobility.util.CustomInInterceptor.handleMessage(CustomInInterceptor.java:77) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:244) at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:110) at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:98) at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:423) at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:139) at org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:142) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:179) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:103) at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:159) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Thread.java:619) 04-oct-2010 11:46:52 org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging ADVERTENCIA: Interceptor for {http://service.mobile.mobility.ica.com/}IRestService has thrown exception, unwinding now org.apache.cxf.interceptor.Fault at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:67) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:293) at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:110) at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:98) at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:423) at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:139) at org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:142) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:179) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:103) at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:159) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Thread.java:619) Caused by: java.lang.NullPointerException at java.lang.Class.isAssignableFrom(Native Method) at org.apache.cxf.jaxrs.utils.InjectionUtils.isSupportedCollectionOrArray(InjectionUtils.java:554) at org.apache.cxf.jaxrs.provider.JAXBElementProvider.isReadable(JAXBElementProvider.java:89) at org.apache.cxf.jaxrs.provider.ProviderFactory.matchesReaderCriterias(ProviderFactory.java:457) at org.apache.cxf.jaxrs.provider.ProviderFactory.chooseMessageReader(ProviderFactory.java:425) at org.apache.cxf.jaxrs.provider.ProviderFactory.createMessageBodyReader(ProviderFactory.java:269) at org.apache.cxf.jaxrs.provider.ProviderFactory.createMessageBodyReader(ProviderFactory.java:279) at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:960) at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:575) at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:540) at com.ica.mobility.util.CustomInInterceptor.processRequest(CustomInInterceptor.java:242) at com.ica.mobility.util.CustomInInterceptor.handleMessage(CustomInInterceptor.java:77) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:244) ... 28 more 04-oct-2010 11:46:52 org.apache.cxf.phase.PhaseInterceptorChain unwind ADVERTENCIA: Exception in handleFault on interceptor org.apache.cxf.binding.xml.interceptor.xmlfaultoutintercep...@d445e2 org.apache.cxf.interceptor.Fault at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:67) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:293) at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:110) at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:98) at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:423) at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:139) at org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:142) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:179) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:103) at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:159) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Thread.java:619) Caused by: java.lang.NullPointerException at java.lang.Class.isAssignableFrom(Native Method) at org.apache.cxf.jaxrs.utils.InjectionUtils.isSupportedCollectionOrArray(InjectionUtils.java:554) at org.apache.cxf.jaxrs.provider.JAXBElementProvider.isReadable(JAXBElementProvider.java:89) at org.apache.cxf.jaxrs.provider.ProviderFactory.matchesReaderCriterias(ProviderFactory.java:457) at org.apache.cxf.jaxrs.provider.ProviderFactory.chooseMessageReader(ProviderFactory.java:425) at org.apache.cxf.jaxrs.provider.ProviderFactory.createMessageBodyReader(ProviderFactory.java:269) at org.apache.cxf.jaxrs.provider.ProviderFactory.createMessageBodyReader(ProviderFactory.java:279) at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:960) at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:575) at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:540) at com.ica.mobility.util.CustomInInterceptor.processRequest(CustomInInterceptor.java:242) at com.ica.mobility.util.CustomInInterceptor.handleMessage(CustomInInterceptor.java:77) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:244) ... 28 more 04-oct-2010 11:46:52 org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver onMessage GRAVE: Error occurred during error handling, give up! org.apache.cxf.interceptor.Fault at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:67) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:293) at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:110) at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:98) at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:423) at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:139) at org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:142) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:179) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:103) at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:159) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Thread.java:619) Caused by: java.lang.NullPointerException at java.lang.Class.isAssignableFrom(Native Method) at org.apache.cxf.jaxrs.utils.InjectionUtils.isSupportedCollectionOrArray(InjectionUtils.java:554) at org.apache.cxf.jaxrs.provider.JAXBElementProvider.isReadable(JAXBElementProvider.java:89) at org.apache.cxf.jaxrs.provider.ProviderFactory.matchesReaderCriterias(ProviderFactory.java:457) at org.apache.cxf.jaxrs.provider.ProviderFactory.chooseMessageReader(ProviderFactory.java:425) at org.apache.cxf.jaxrs.provider.ProviderFactory.createMessageBodyReader(ProviderFactory.java:269) at org.apache.cxf.jaxrs.provider.ProviderFactory.createMessageBodyReader(ProviderFactory.java:279) at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:960) at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:575) at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:540) at com.ica.mobility.util.CustomInInterceptor.processRequest(CustomInInterceptor.java:242) at com.ica.mobility.util.CustomInInterceptor.handleMessage(CustomInInterceptor.java:77) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:244) ... 28 more {code} I hope you have all the information you need. Cheers, Ivan -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online.