简体   繁体   中英

ClassCastException when doing serialization using Jackson ObjectMapper - java.lang.object as value in underlying HashMap used in LinkedHashset

Yes, the title is quite confusing, I know!

I'm using Jackson ObjectMapper to serialize a LnkedHashSet of type MyClass. This is how stuff is added to that HashSet

private LinkedHashSet<MyClass> causeEntities;
this.causeEntities.add(new MyClass("foo"));

Now, when Jackson tries to serialize this, it throws a ClassCastException saying java.lang.Object cannot be cast to MyClass. I debugged into what "add" in LinkedHashSet does and it adds it into a Map, with the key as MyClass and value as a dummy Object

private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

So, the final LinkedHashSet that Jackson gets contains a HashMap, which in turn is a key-value pair of MyClass-Object, and this Object is giving me a nightmare.

Any ideas on how to tackle this would highly be appreciated. I'm a novice and I would be glad if someone could help, thanks!

2013/11/12 17:32:30,058 SEVERE [com.servicebridge.service] : org.codehaus.jackson.map.JsonMappingException: [Ljava.lang.Object; cannot be cast to [Lcom.MyClass; (through reference chain: com.blah.ABC["details"]->com.blah.DEF["validationAppErrors"]->com.blah.GHI["causeEntity"])
    at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:218) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:183) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.std.SerializerBase.wrapAndThrow(SerializerBase.java:140) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:158) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.std.ObjectArraySerializer.serializeContents(ObjectArraySerializer.java:123) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.std.ObjectArraySerializer.serializeContents(ObjectArraySerializer.java:29) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.std.StdArraySerializers$ArraySerializerBase.serialize(StdArraySerializers.java:56) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ObjectMapper._configAndWriteValue(ObjectMapper.java:2568) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ObjectMapper.writeValueAsString(ObjectMapper.java:2090) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at com.blah.JKL.invokeService(JKL.java:106) [classes:]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_11]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_11]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_11]
    at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_11]
    at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:180) [cxf-api-2.7.5.jar:2.7.5]
    at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) [cxf-api-2.7.5.jar:2.7.5]
    at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:198) [cxf-bundle-jaxrs-2.7.5.jar:2.7.5]
    at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:100) [cxf-bundle-jaxrs-2.7.5.jar:2.7.5]
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58) [cxf-api-2.7.5.jar:2.7.5]
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:94) [cxf-api-2.7.5.jar:2.7.5]
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271) [cxf-api-2.7.5.jar:2.7.5]
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) [cxf-api-2.7.5.jar:2.7.5]
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:239) [cxf-bundle-jaxrs-2.7.5.jar:2.7.5]
    at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:223) [cxf-bundle-jaxrs-2.7.5.jar:2.7.5]
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:203) [cxf-bundle-jaxrs-2.7.5.jar:2.7.5]
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:137) [cxf-bundle-jaxrs-2.7.5.jar:2.7.5]
    at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:158) [cxf-bundle-jaxrs-2.7.5.jar:2.7.5]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:243) [cxf-bundle-jaxrs-2.7.5.jar:2.7.5]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:163) [cxf-bundle-jaxrs-2.7.5.jar:2.7.5]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) [jboss-servlet-api_3.0_spec-1.0.1.Final.jar:1.0.1.Final]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:219) [cxf-bundle-jaxrs-2.7.5.jar:2.7.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.17.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.17.Final.jar:]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:366) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:99) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at com.blah.MNO.doFilter(MNO.java:93) [foo-1.0.jar:]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at com.blah.PQR.doFilter(PQR.java:113) [foo-1.0.jar:]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:167) [spring-security-web-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) [spring-web-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.17.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.17.Final.jar:]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.17.Final.jar:]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.17.Final.jar:]
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:165) [jboss-as-web-7.1.3.Final.jar:7.1.3.Final]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.17.Final.jar:]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.17.Final.jar:]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.17.Final.jar:]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:372) [jbossweb-7.0.17.Final.jar:]
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.17.Final.jar:]
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:679) [jbossweb-7.0.17.Final.jar:]
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:931) [jbossweb-7.0.17.Final.jar:]
    at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_11]
Caused by: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lcom.MyClass;
    at com.blah.GHI.getCauseEntity(GHI.java:80) [web-sim-1.0.jar:]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_11]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_11]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_11]
    at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_11]
    at org.codehaus.jackson.map.ser.BeanPropertyWriter.get(BeanPropertyWriter.java:483) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:418) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150) [jackson-mapper-asl-1.9.3.jar:1.9.3]
    ... 75 more
 Caused by: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lcom.MyClass; at com.blah.GHI.getCauseEntity(GHI.java:80) [web-sim-1.0.jar:] 

I'll hazard a bit of crystal-ball debugging here: based on the stack trace, the error has nothing to do with serialization itself, but rather with trying to cast an Object[] to a MyClass[] in GHI.java .

Are you by some chance using .toArray() on a generic collection with no argument? This will return an Object[] which cannot be subjected to a narrowing cast. In that case, use the one-argument overload , .toArray(new MyClass[0]) , to ensure that the created array is of the correct type.

If you are unable to post actual code and have to resort to obfuscation like GHI , JKL , MyClass and so forth, that will make troubleshooting much more difficult.

Code that fixed my problem:

Before:

return (MyClass[]) ((this.causeEntities == null ) ? null : this.causeEntities.toArray());

After:

return (MyClass[]) ((this.causeEntities == null ) ? null : this.causeEntities.toArray(new MyClass[this.causeEntities.size()]));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM