ClassNotFoundException via org.springframework.security.oauth_1.0.0.RC3
I am migrating a medium-sized Spring deployment from Tomcat 7 to Virgo (Tomcat of course). I added Manifest.MF data (OSGi information) to our projects and most of my API is working fine. However, I am encountering an error during Oauth2 authentication. From what I can tell, the "oauth_access_token" table in our database is storing a couple of blobs ("token" and "authentication") that reference our custom org.springframework.security.core.userdetails.User extension (referred to here as "CustomUser").
I am curious why this exception is arising and I can only see a few general possibilities:
1) We had a flawed configuration beforehand that only worked because Tomcat is not as rigorous about its configuration as Virgo.
2) Virgo requires extra information regarding this module that Tomcat does not.
3) I futzed up a configuration file or resource location while converting my API to OSGi bundles.
Here is the primary exception:
Code:
[2012-12-20 14:28:07.495] ERROR http-bio-8080-exec-4 o.a.c.c.C.[Catalina].[localhost].[/api-0.0.1-SNAPSHOT].[api] Servlet.service() for servlet [api] in context with path [/api-0.0.1-SNAPSHOT] threw exception java.lang.IllegalArgumentException: org.eclipse.virgo.kernel.osgi.framework.ExtendedClassNotFoundException: com.c.security.user.CustomUser in KernelBundleClassLoader: [bundle=org.springframework.security.oauth_1.0.0.RC3]
at org.springframework.security.oauth2.common.util.SerializationUtils.deserialize(SerializationUtils.java:43)
at org.springframework.security.oauth2.provider.token.JdbcTokenStore.deserializeAuthentication(JdbcTokenStore.java:312)
at org.springframework.security.oauth2.provider.token.JdbcTokenStore$3.mapRow(JdbcTokenStore.java:173)
at org.springframework.security.oauth2.provider.token.JdbcTokenStore$3.mapRow(JdbcTokenStore.java:171)
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:92)
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:1)
at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:649)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:587)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:637)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:666)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:674)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:734)
at org.springframework.security.oauth2.provider.token.JdbcTokenStore.readAuthentication(JdbcTokenStore.java:170)
at org.springframework.security.oauth2.provider.token.JdbcTokenStore.readAuthentication(JdbcTokenStore.java:163)
at org.springframework.security.oauth2.provider.token.DefaultTokenServices.loadAuthentication(DefaultTokenServices.java:200)
at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager.authenticate(OAuth2AuthenticationManager.java:70)
at org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter.doFilter(OAuth2AuthenticationProcessingFilter.java:108)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.eclipse.virgo.web.tomcat.support.ApplicationNameTrackingValve.invoke(ApplicationNameTrackingValve.java:33)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: org.eclipse.virgo.kernel.osgi.framework.ExtendedClassNotFoundException: com.c.security.user.CustomUser in KernelBundleClassLoader: [bundle=org.springframework.security.oauth_1.0.0.RC3]
at org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader.loadClass(KernelBundleClassLoader.java:139)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:603)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at org.springframework.security.oauth2.common.util.SerializationUtils.deserialize(SerializationUtils.java:36)
... 43 common frames omitted
Caused by: java.lang.ClassNotFoundException: com.c.security.user.CustomUser
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:501)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
at org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader.loadClass(KernelBundleClassLoader.java:135)
... 61 common frames omitted
The only really significant change that I can think of is that I've migrated our MyBatis data mappers from one project into another. I've been trying to dig up other cases of this but there is very little intersection on Google between Virgo and OAuth2 =(
I can supplement this data if needed. Any thoughts?