springserializationspring-securityspring-4spymemcached

How do I figure out what object my session is trying to serialize?


I recently upgraded to Spring Security 4.2.3.RELEASE. I'm also using spymemcached v 2.8.4. I'm running into this situation where for some reason Spring is trying to serialize service implementation classes. I can't figure out where this is coming from. The line of my code that the exception refers to is

Set<Session> userSessions = (Set<Session>) memcachedClient.get(userId);
...
memcachedClient.set(userId, sessionTimeoutInSeconds.intValue(), userSessions); // dies here

with the mysterious error (the "java.io.NotSerializableException: org.mainco.subco.ecom.service.ContractServiceImpl" is buried within) ...

09:06:47,771 ERROR [io.undertow.request] (default task-58) UT005023: Exception handling request to /myproject/registration/save: java.lang.IllegalArgumentException: Non-serializable object
    at net.spy.memcached.transcoders.BaseSerializingTranscoder.serialize(BaseSerializingTranscoder.java:110)
    at net.spy.memcached.transcoders.SerializingTranscoder.encode(SerializingTranscoder.java:162)
    at net.spy.memcached.MemcachedClient.asyncStore(MemcachedClient.java:282)
    at net.spy.memcached.MemcachedClient.set(MemcachedClient.java:733)
    at net.spy.memcached.MemcachedClient.set(MemcachedClient.java:126)
    at org.mainco.subco.session.service.MemcachedSessionService.associateUser(MemcachedSessionService.java:365)
    at org.mainco.subco.session.service.MemcachedSessionService.setSessionSecurityContext(MemcachedSessionService.java:288)
    at org.mainco.subco.core.security.SubcoSecurityContextRepository.saveContext(subcoSecurityContextRepository.java:116)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:114)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
    at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85)
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:72)
    at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
    at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:284)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:174)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:198)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:784)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.NotSerializableException: org.mainco.subco.ecom.service.ContractServiceImpl
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)

How do I figure out the object memcache is trying to serialize and thus figure out how it is referencing a service class to serialize?

The point of this question is not how do I make my service class serializable but why is my session trying to serialize it in the first place.


Solution

  • I'm running into this situation where for some reason Spring is trying to serialize service implementation classes.

    spring don't try to serialize implementation .

    looks lite when you do

    memcachedClient.set(userId, sessionTimeoutInSeconds.intValue(), userSessions);
    

    it's expect for Serializable object ,but userSessions is not.

    Set is not serializable , and type that you get

    (Set) memcachedClient.get(userId);

    is not serialized to. check if you can cast memcachedClient.get(userId) to something that is Serializable like HashSets or TreeSet ....

    the worst it's you can try BUT you might get CastException

    memcachedClient.set(userId, sessionTimeoutInSeconds.intValue(), (Serializable)userSessions);


    you can iterate set and do simple check :

    int count=0;
    for(Session session: userSessions ){
        log....
        boolean isSerializable = checkIfSerializable(session);
        count=isSerializable ? count+1 : count;
        log 
    }
    
    private static boolean checkIfSerializable(Object value) throws IllegalAccessException {
        try {
            ByteArrayOutputStream bf = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bf);
            oos.writeObject(value);
            oos.close();
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bf.toByteArray()));
            Object o = ois.readObject();
            return true;
    
        } catch (Exception e) {
            System.out.println("----->>>> Not exactly Serializable : " + value);
        }
            return false;
    }