Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[jetty-dev] Classloader issue reloading UserIdentity session attribute

I have a custom session data store implementation backed by Redis.
Everything working except ability to reload UserIdentity session attribute.

For example, this works

  • Start up Redis
  • Start up one instance of Jetty server, using default L1 cache, and custom L2 redis cache
  • Run an example servlet that implements a counter and sets as session attribute
  • Stop Jetty instance (to flush L1 cache)
  • Restart Jetty instance
  • Refresh browser page, thus attempting to reconnect to same session
  • Session is not found in L1
  • Session loaded from L2 Redis successfully
  • Session attribute counter resumes counting up from previous value ✅

That all works fine.

However if I login prior to shutting down Jetty, then restart Jetty, then attempt to reload that session I get an error of

2021-09-09 23:17:36.739:WARN :oejs.HttpChannel:qtp1798286609-22: /Home
java.lang.IllegalStateException: !UserIdentity
    at org.eclipse.jetty.server.Request.getUserPrincipal(

Working back from that I see the issue is most likely when the UserIdentity session attribute is deserialized, I see the "!SecurityHandler" log

2021-09-09 23:17:36.724:DEBUG:oejss.SessionData:lettuce-nioEventLoop-4-1: Deserialize isServerLoader=true serverLoader=jdk.internal.loader.ClassLoaders$AppClassLoader@22d8cfe0 tccl=WebAppClassLoader{root}@29d89d5d
2021-09-09 23:17:36.726:DEBUG:oejsa.SessionAuthentication:lettuce-nioEventLoop-4-1: !SecurityHandler

Which comes from SessionAuthentication.readObject

SecurityHandler security = SecurityHandler.getCurrentSecurityHandler();
if (security == null)
    if (LOG.isDebugEnabled())

I do notice that all the other session attributes, which all work, have isServerLoader=false whereas UserIdentity has isServerLoader=true

For deserialization I used the FileSessionDataStore as a guide and have this

ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is);
  SessionData.deserializeAttributes(data, ois);

and for serialization I have

ObjectOutputStream oos = new ObjectOutputStream(out);
SessionData.serializeAttributes(value, oos);

Logging from the serialize is as follows, via a custom RedisCodec class, perhaps the Lettuce Redis client running it on an async netty event loop thread is a problem?

2021-09-09 23:17:06.021:DEBUG:oejss.SessionData:lettuce-nioEventLoop-4-1: Attribute isServerLoader=true

Any pointers would be appreciated


Back to the top