Issue casting a REST request object to an OpenMRSObject

Hi All,

We are using the webservices.rest module to make RESTful calls in our OpenHMIS cashier module.

However, our calls are failing with: “java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to org.openmrs.OpenmrsObject”. The exception is thrown by the webservices.rest module.

Has anyone come across this before? I can give more details and code samples as needed.

Thanks -Andrew

1 Like

Hey @insiderish, Can you provide a stack trace, the version of webservices.rest that you are using and the call made, so that the issue can be reproduced?

Hi Vinay,

Thanks for the prompt reply. We are using webservice module 2.11.

Here is the full stack trace.

Thanks -Andrew

ERROR - BaseRestController.handleException(90) |2015-12-21 20:25:19,256| attributeTypes on class org.openmrs.module.openhmis.cashier.api.model.PaymentMode org.openmrs.module.webservices.rest.web.response.ConversionException: attributeTypes on class org.openmrs.module.openhmis.cashier.api.model.PaymentMode at org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource.setProperty(BaseDelegatingResource.java:802) at org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource.setConvertedProperties(BaseDelegatingResource.java:650) at org.openmrs.module.webservices.rest.web.resource.impl.DelegatingCrudResource.create(DelegatingCrudResource.java:93) at org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceController.create(MainResourceController.java:86) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176) at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426) at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560) at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.openmrs.module.web.filter.ForcePasswordChangeFilter.doFilter(ForcePasswordChangeFilter.java:61) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.openmrs.module.web.filter.ModuleFilterChain.doFilter(ModuleFilterChain.java:72) at org.openmrs.web.filter.GZIPFilter.doFilterInternal(GZIPFilter.java:55) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.openmrs.module.web.filter.ModuleFilterChain.doFilter(ModuleFilterChain.java:70) at org.openmrs.module.webservices.rest.web.filter.AuthorizationFilter.doFilter(AuthorizationFilter.java:108) at org.openmrs.module.web.filter.ModuleFilterChain.doFilter(ModuleFilterChain.java:70) at org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInternal(ShallowEtagHeaderFilter.java:58) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.openmrs.module.web.filter.ModuleFilterChain.doFilter(ModuleFilterChain.java:70) at org.openmrs.module.web.filter.ModuleFilter.doFilter(ModuleFilter.java:54) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.openmrs.web.filter.OpenmrsFilter.doFilterInternal(OpenmrsFilter.java:107) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 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:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:105) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:105) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:105) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.openmrs.module.webservices.rest.web.resource.impl.BaseDelegatingResource.setProperty(BaseDelegatingResource.java:776) … 68 more Caused by: java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to org.openmrs.OpenmrsObject at org.openmrs.module.webservices.rest.resource.BaseRestDataResource.syncCollection(BaseRestDataResource.java:79) at org.openmrs.module.webservices.rest.resource.BaseRestDataResource.syncCollection(BaseRestDataResource.java:59) ** at org.openmrs.module.webservices.rest.resource.BaseRestInstanceTypeResource.setAttributeTypes(BaseRestInstanceTypeResource.java:46)** at org.openmrs.module.webservices.rest.resource.PaymentModeResource.setAttributeTypes(PaymentModeResource.java:59) at org.openmrs.module.webservices.rest.resource.PaymentModeResource.setAttributeTypes(PaymentModeResource.java:33) … 73 more

Is it easy to provide a unit test to reproduce this?

It is also important to mention whether you ran into this while posting or fetching data

Hi all,

Thanks for the replies.

I am running into the error while posting (saving) data. Unfortunately, I don’t have a unit case but it’s something I can work on.

To reproduce the issue on our demo site:

  • Login with credentials: demo/Demo1234.
  • Navigate to “Administration”.
  • Under “OpenHMIS Cashier Module” click on “Manage Payment Modes”.
  • Click on the “Add Payment Mode” link. Enter the Name and Description fields.
  • Click on the “Add” button under “Attribute Types”.
  • On the popup window enter “Name”.
  • Under format select “org.openmrs.Person”.
  • Click Ok.
  • And finally click the “Create Payment Mode” button.

These are my findings based on lots of debugging.

We have a PaymentModeResource class which extends BaseRestInstanceTypeResource.

BaseRestInstanceTypeResource has a setAttributeTypes method with generic types. PaymentModeResource overrides the method and marks it with a PropertySetter annotation.

For some reason, webservices.module’s ReflectionUtil selects the setAttributeTypes method from BaseRestInstanceTypeResource and NOT PaymentModeResource hence the cast exception.

Question: How does the PropertySetter annotation work with generics? Shouldn’t the child’s overridden method take precedence over the parent one?

I will try to get a unit test case soonest possible.

Thanks

-Andrew

Trying to get a hold of Andrew Moko - please reach out to me - edwin@afyanetworks.com looking for assistance finding someone to implement openMRS and OpenHMIS for a proof of concept project I have. - email me on edwin.momanyi■■■■■■■■■■, copy edwin@afyanetworks.com

That doesn’t look exactly correct, you need 3 resources i.e PaymentMode, PaymentModeAttribute and PaymentAttributeTypeResource, i suggest your payment mode attribute and attribute type resources extend BaseAttributeCrudResource1_9 and BaseAttributeTypeCrudResource1_9 respectively, just look at VisitResource1_9 and VisitAttributeResource1_9 and VisitAttributeTypeResource then try to replicate that.