ClassCastException when using Rest API service and JodaModule
search cancel

ClassCastException when using Rest API service and JodaModule

book

Article ID: 294339

calendar_today

Updated On:

Products

VMware Tanzu Gemfire

Issue/Introduction

If you enable Rest API service in the cacheserver while also using com.fasterxml.jackson.datatype.joda.JodaModule in function execution service whose class is loaded in classpath, you may see the below error:
[warning 2019/09/13 05:43:21.677 BST rd1-server <main> tid=0x1] Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter]: Constructor threw exception; nested exception is java.lang.ClassCastException: com.fasterxml.jackson.datatype.joda.JodaModule cannot be cast to com.fasterxml.jackson.databind.Module

[error 2019/09/13 05:43:21.681 BST rd1-server <main> tid=0x1] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter]: Constructor threw exception; nested exception is java.lang.ClassCastException: com.fasterxml.jackson.datatype.joda.JodaModule cannot be cast to com.fasterxml.jackson.databind.Module
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1163)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1107)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:634)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:682)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:553)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:171)
    at javax.servlet.GenericServlet.init(GenericServlet.java:244)
    at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:670)
    at org.eclipse.jetty.servlet.ServletHolder.initialize(ServletHolder.java:427)
    at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:760)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:374)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1497)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1459)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:847)
    at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:287)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:545)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:138)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:117)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:138)
    at org.eclipse.jetty.server.Server.start(Server.java:416)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:108)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
    at org.eclipse.jetty.server.Server.doStart(Server.java:383)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.apache.geode.management.internal.JettyHelper.startJetty(JettyHelper.java:165)
    at org.apache.geode.management.internal.ManagementAgent.startHttpService(ManagementAgent.java:297)
    at org.apache.geode.management.internal.ManagementAgent.startAgent(ManagementAgent.java:150)
    at org.apache.geode.management.internal.SystemManagementService.startManager(SystemManagementService.java:429)
    at org.apache.geode.management.internal.beans.ManagementAdapter.handleCacheCreation(ManagementAdapter.java:173)
    at org.apache.geode.management.internal.beans.ManagementListener.handleEvent(ManagementListener.java:115)
    at org.apache.geode.distributed.internal.InternalDistributedSystem.notifyResourceEventListeners(InternalDistributedSystem.java:2185)
    at org.apache.geode.distributed.internal.InternalDistributedSystem.handleResourceEvent(InternalDistributedSystem.java:596)
    at org.apache.geode.internal.cache.GemFireCacheImpl.initialize(GemFireCacheImpl.java:1211)
    at org.apache.geode.internal.cache.GemFireCacheImpl.basicCreate(GemFireCacheImpl.java:797)
    at org.apache.geode.internal.cache.GemFireCacheImpl.create(GemFireCacheImpl.java:783)
    at org.apache.geode.cache.CacheFactory.create(CacheFactory.java:176)
    at org.apache.geode.cache.CacheFactory.create(CacheFactory.java:223)
    at org.apache.geode.distributed.internal.DefaultServerLauncherCacheProvider.createCache(DefaultServerLauncherCacheProvider.java:52)
    at org.apache.geode.distributed.ServerLauncher.createCache(ServerLauncher.java:860)
    at org.apache.geode.distributed.ServerLauncher.start(ServerLauncher.java:777)
    at org.apache.geode.distributed.ServerLauncher.run(ServerLauncher.java:707)
    at org.apache.geode.distributed.ServerLauncher.main(ServerLauncher.java:227)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter]: Constructor threw exception; nested exception is java.lang.ClassCastException: com.fasterxml.jackson.datatype.joda.JodaModule cannot be cast to com.fasterxml.jackson.databind.Module
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:154)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:89)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1155)
    ... 55 more
Caused by: java.lang.ClassCastException: com.fasterxml.jackson.datatype.joda.JodaModule cannot be cast to com.fasterxml.jackson.databind.Module
    at org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.registerWellKnownModulesIfAvailable(Jackson2ObjectMapperBuilder.java:764)
    at org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.configure(Jackson2ObjectMapperBuilder.java:607)
    at org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.build(Jackson2ObjectMapperBuilder.java:590)
    at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.<init>(MappingJackson2HttpMessageConverter.java:57)
    at org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter.<init>(AllEncompassingFormHttpMessageConverter.java:66)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.<init>(RequestMappingHandlerAdapter.java:182)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142)
    ... 57 more


Environment

Product Version: 9.7

Resolution

Root Cause Analysis

When gemfire cacheserver with rest api webapp starts up, it loads com.fasterxml.jackson.databind.Module (it is an abstract class) using the webapp’s classloader.

Spring attempts to load various ObjectMappers (Jackson2ObjectMapperBuilder.java), and it finds the JodaModule (it extends from Module) from the system classpath.

In order to resolve the com.fasterxml.jackson.datatype.joda.JodaModule class by the system classloader, it also needs to load the com.fasterxml.jackson.databind.Module which is then also loaded by system classloader. However, this means that the JodaModule is not compatible with the com.fasterxml.jackson.databind.Module class loaded by the webapp classloader, then it will result in this castexception.


Workaround

As long as all the necessary jackson jars are on the system classpath, a quick workaround would be to remove all the jackson jars from the webapp jar such as using zip -d command to remove jackson*.jar.

For example:

zip -d /gemfireInstallationPath/tools/Extensions/geode-web-api-9.7.0.war WEB-INF/lib/jackson\*

Note: This is a known issue which has been reported as GEM-2705. A fix is currently being worked on.