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.
You can determine whether an object is serializable at run time by retrieving the value of the IsSerializable property of a Type object that represents that object's type.
Serialization is the writing part, and deserialization is the reading part. So your user logs in. You don't want to keep all his info in the session because it's already in your database. But on subsequent requests, you want to remember who he is. So all you have to write down on your post-it is his Id, let's say 1234.
Serialization is the process of converting an object into a stream of bytes to store the object or transmit it to memory, a database, or a file. Its main purpose is to save the state of an object in order to be able to recreate it when needed. The reverse process is called deserialization.
You can think of serialization as the process of converting an object instance into a sequence of bytes (which may be binary or not depending on the implementation). It is very useful when you want to transmit one object data across the network, for instance from one JVM to another.
Why don't you try to enumerate the sessions and the attributes and java-serialize them to a dummy output stream until one fails ? when it fails you print attribute name and value class.
I suppose session
is org.apache.catalina.Session
. In your code add:
for(Session x : userSessions) checkSerializable(x.getSession());
with checkSerializable
:
private static void checkSerializable(HttpSession s) {
Enumeration e = s.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String) e.nextElement();
Object value = s.getAttribute(name);
try
{
ObjectOutputStream out=new ObjectOutputStream(new ByteArrayOutputStream());
out.writeObject(value);
}
catch(NotSerializableException ex)
{
ex.printStackTrace();
System.out.println(name + " is not serializable, class is: " + value.getClass().getName());
}
catch(IOException e2)
{
throw new RuntimeException("Unexpected", e2);
}
}
}
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With