spring-loaded icon indicating copy to clipboard operation
spring-loaded copied to clipboard

ClassNotFoundException when using with Tomcat

Open antoineroux opened this issue 10 years ago • 3 comments

Hello, I thought I would give a try to Spring Loaded when developing against a Java app on Tomcat.

I am using Tomcat 8.0.15, JDK 8, and various Spring frameworks and libs. Application startup goes ok, but when I try to connect, I get this kind of stacktrace:

2015-02-23 18:05:46,736 WARN [http-nio-8080-exec-4] org.springframework.security.oauth2.provider.token.store.JdbcTokenStore - Failed to deserialize authentication for 490e8e49-32d0-4b4f-b8dd-089996e9b76b - 36553 
java.lang.IllegalArgumentException: java.lang.ClassNotFoundException: org.springframework.security.core.authority.SimpleGrantedAuthority
    at org.springframework.security.oauth2.common.util.SerializationUtils.deserialize(SerializationUtils.java:43)
    at org.springframework.security.oauth2.provider.token.store.JdbcTokenStore.deserializeAuthentication(JdbcTokenStore.java:385)
    at org.springframework.security.oauth2.provider.token.store.JdbcTokenStore$3.mapRow(JdbcTokenStore.java:194)
    at org.springframework.security.oauth2.provider.token.store.JdbcTokenStore$3.mapRow(JdbcTokenStore.java:1)
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:92)
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:60)
    at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:651)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:589)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:639)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:668)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:676)
    at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:736)
    at org.springframework.security.oauth2.provider.token.store.JdbcTokenStore.readAuthentication(JdbcTokenStore.java:191)
    at org.springframework.security.oauth2.provider.token.store.JdbcTokenStore.readAuthentication(JdbcTokenStore.java:184)
    at org.springframework.security.oauth2.provider.token.DefaultTokenServices.loadAuthentication(DefaultTokenServices.java:216)
    at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager.authenticate(OAuth2AuthenticationManager.java:70)
    at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.java:117)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.mycompany.myapp.central.TimeFilter.doFilter(TimeFilter.java:39)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.mycompany.myapp.auth.AuthHeaderFilter.doFilter(AuthHeaderFilter.java:45)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:613)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:673)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1513)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: org.springframework.security.core.authority.SimpleGrantedAuthority
    at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:344)
    at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:626)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1613)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
    at java.util.ArrayList.readObject(ArrayList.java:791)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1270)
    at sun.reflect.GeneratedMethodAccessor271.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at java.io.ObjectStreamClass.__sljlrmi(ObjectStreamClass.java)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1896)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1993)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1918)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1993)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1918)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
    at org.springframework.security.oauth2.common.util.SerializationUtils.deserialize(SerializationUtils.java:36)
    ... 55 more

So it seems the app cannot find SimpleGrantedAuthority, which is part of Spring Security. I tried with Spring Loaded 1.2.1 and the latest 1.2.2 snapshot. I got the same error with both.

How can I solve that or provide more information?

antoineroux avatar Feb 23 '15 17:02 antoineroux

It looks like you're running into a similar issue that I was. I was having problems cloning objects due to a ClassNotFoundException when invoking readObject on an ObjectInputStream. The solution I stumbled upon involved using a specialized ObjectInputStream that took in the target Object's classloader as an argument. There are many options out there to achieve this, in my case I used org.apache.catalina.util.CustomObjectInputStream and haven't seen the error since:

ObjectInputStream ois = new CustomObjectInputStream(bais, targetObj.getClass().getClassLoader());

In your case however it looks like you're encountering the error through a third party:

org.springframework.security.oauth2.common.util.SerializationUtils.deserialize

If you have control over the code that uses that utility... you'll need to either find a serialization utility that handles this situation correctly or implement your own solution with a specialized ObjectInputStream.

Hope this helps.

jlindblom42 avatar Feb 26 '15 22:02 jlindblom42

Thanks a lot for the answer! As you said, this happens in third party code, and it seems complicated to change it at the moment. So I guess I will leave this experiment for now.

antoineroux avatar Feb 27 '15 10:02 antoineroux

This is caused by this bug: https://github.com/spring-projects/spring-loaded/issues/107

skopf avatar Mar 03 '15 15:03 skopf