views:

101

answers:

6

We have an annoying log message coming from Weblogic whenever we invalidate the HTTPSession when it has objects that are not serializable (which we don't care about but which is polluting our logs). Tweaking our log4j configuration to not log this message does not appear to be an option (the message is coming from a generic Weblogic class and we dont want to supress all messages from this class and other than writing our own adapter to look at messages about to be written to the log and suppressing the deserialization error messages I dont know how we would do it through log4j configuration).

In order to temporarily fix this to clean up our logs I want to intercept calls to add objects to the HTTP Session so that the class of the object being added (and any objects in its object graph) have their instance variable declarations changed to transient. Figured I would intercept calls by adding an HTTPSesssionEventListener and then modifying the Class's instances variables using the reflection libraries.

Does anyone know if this would work?

A: 

Try modifying the ObjectOutputStream, not the serialized object.

If you extend ObjectOutputStream, you can override the replaceObject method and clear the non-serializable fields or re-create the object without the non-serializable properties.

Another option is to use reflection to nullify the non-serializable fields of the session objects, but that is very risky as a session object could be loaded back and appear to work but then throw a NullPointerException hours or even months later (when the field you nullified is eventually referenced.)

Modifying the classes will probably not work.

It is possible to extend ClassLoader and tweak flags on instance fields but:

  • If it's your class that contains the non-serializable field then it's simpler to change the code yourself to make it transient
  • If it's not your class then it will be loaded by a different ClassLoader from your application classes so by the time you see the object it will be too late (because the class has already been loaded.)

You cannot set the transient flag on an individual object, only on a class.

finnw
It's the app server that is doing the serialisation.
Tom Hawtin - tackline
A: 

Why go to that trouble? It sounds just as easy to mark them all as Serializable, as long as all the objects in question are yours.

If that's not possible, .aAnother way is to have a class registered within your webApp that implements HttpSessionAttributeListener. In the attributeAdded method print the sessionID and then serialize the session data:

public void attributeAdded(HttpSessionBindingEvent hsbe)
{
    // Handle the details yourself here.
    ObjectOutputStream.writeObject(hsbe.getValue())
}
duffymo
trying to get arround not going through the classes (there are hundreds of them to mark them serializable and any other objects in their object graph as serializable
stamp31sd
+1  A: 

One option if would be

tail -f yourlog | grep -v "annoying line here" > cleanLogFile

Which is much less intrusive. But creates a second file.

I did this for a project where I needed to trace an specific problem and all those stupid messages where getting in the middle.

OscarRyz
thanks-- this works for what i need
stamp31sd
@stamp31sd: I'm glad. So, would my answer be marked as accepted? ( you know the green thick over there :P )
OscarRyz
+2  A: 

Does anyone have a better suggestion and/or know if this will/will not work like I would want it to?

Yes. Build to spec!

In compliance with the Java Servlet specification:

The distributed servlet container must throw an IllegalArgumentException for objects where the container cannot support the mechanism necessary for migration of the session storing them.

So if you want to avoid this message (and write good portable and distributable code), just make the object you put in HttpSession implement the Serializable interface.

Seriously, I can't believe you are thinking to a solution to workaround the real problem instead of fixing it.

Pascal Thivent
i didnt write this code, i inherited it. this is an interim fix and not intended in anway to be a real fix. plan is to incrementily fix the app as quick as we can but we need the logs cleaned up now so that we can better debug other production errors.
stamp31sd
Besides, how hard can it be to add "Serializable" with a decent IDE? How long could it take - maybe a day's effort? The hack will take longer than the fix. +1 from me.
duffymo
+1 - interim hack fixes are a bad idea. Just fix it properly.
Stephen C
A: 

As your sessions don't seem to be serializable, anyway, you might consider switching of this feature completely. Why would you want to deserialize sessions that have not been correctly serialized?

Wolfgang
A: 

tailing the logs with a good grep pattern does the trick and is the non-invasive solution i was looking for. thanks oscar reyes.

stamp31sd