Page tree
Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

 

Intro

MGNLUI-351 - Getting issue details... STATUS

As explained in the issue above Magnolia is currently unable to serialise and deserialise its own Admicentral UI. This is a problem especially in clustered environments where a user session may be serialised across multiple Java VMs.

Goals

We want to detect and remove all serialisation issues in our code.

Furthermore, we want to find a way to detect serialization issues during Magnolia build so that they are caught and tackled early.

Working solution  

Detecting and removing serialization issues

After several attempts (which will be mentioned later on), the only working approach was the following

  • start tomcat with this JVM parameter -Dsun.io.serialization.extendedDebugInfo=true
  • login into Magnolia
  • stop and restart Magnolia
  • in the logs something like the following stack trace will show up

Serialization stacktrace
Jun 16, 2016 3:41:20 PM org.apache.catalina.session.StandardManager doLoad

SEVERE: IOException while loading persisted sessions: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: info.magnolia.event.ResettableEventBus$1
	- field (class "info.magnolia.ui.admincentral.shellapp.applauncher.AppLauncherShellApp$3", name: "val$systemRegistration", type: "interface info.magnolia.event.HandlerRegistration")
	- object (class "info.magnolia.ui.admincentral.shellapp.applauncher.AppLauncherShellApp$3", info.magnolia.ui.admincentral.shellapp.applauncher.AppLauncherShellApp$3@662420ac)
	- field (class "com.vaadin.event.ListenerMethod", name: "target", type: "class java.lang.Object")
	- custom writeObject data (class "com.vaadin.event.ListenerMethod")
	- object (class "com.vaadin.event.ListenerMethod", com.vaadin.event.ListenerMethod@4637e20e)
	- custom writeObject data (class "java.util.HashSet")
	- object (class "java.util.LinkedHashSet", [com.vaadin.event.ListenerMethod@4637e20e])
	- field (class "com.vaadin.event.EventRouter", name: "listenerList", type: "class java.util.LinkedHashSet")
	- object (class "com.vaadin.event.EventRouter", com.vaadin.event.EventRouter@50986eaf)
	- field (class "com.vaadin.server.AbstractClientConnector", name: "eventRouter", type: "class com.vaadin.event.EventRouter")
	- object (class "info.magnolia.ui.vaadin.applauncher.AppLauncher", info.magnolia.ui.vaadin.applauncher.AppLauncher@7a66f618)
	- custom writeObject data (class "java.util.EnumMap")
	- object (class "java.util.EnumMap", {APPLAUNCHER=info.magnolia.ui.vaadin.applauncher.AppLauncher@7a66f618, PULSE=com.vaadin.ui.VerticalLayout@141b10e1, FAVORITE=com.vaadin.ui.VerticalLayout@22f80d16})
	- field (class "info.magnolia.ui.vaadin.gwt.client.magnoliashell.shell.MagnoliaShellState", name: "shellApps", type: "interface java.util.Map")
	- object (class "info.magnolia.ui.vaadin.gwt.client.magnoliashell.shell.MagnoliaShellState", info.magnolia.ui.vaadin.gwt.client.magnoliashell.shell.MagnoliaShellState@4a4fd810)
	- field (class "com.vaadin.server.AbstractClientConnector", name: "sharedState", type: "class com.vaadin.shared.communication.SharedState")
	- object (class "info.magnolia.ui.vaadin.magnoliashell.MagnoliaShell", info.magnolia.ui.vaadin.magnoliashell.MagnoliaShell@6ceda10d)
	- field (class "com.vaadin.ui.AbstractSingleComponentContainer", name: "content", type: "interface com.vaadin.ui.Component")
	- object (class "info.magnolia.ui.admincentral.AdmincentralUI", info.magnolia.ui.admincentral.AdmincentralUI@619fbf56)
	- custom writeObject data (class "java.util.HashMap")
	- object (class "java.util.HashMap", {0=info.magnolia.ui.admincentral.AdmincentralUI@619fbf56})
	- field (class "com.vaadin.server.VaadinSession", name: "uIs", type: "interface java.util.Map")
	- root object (class "com.vaadin.server.VaadinSession", com.vaadin.server.VaadinSession@7238b701)

 

  • With the information provided above try to fix the "offending" class. This usually entails making the class implement Serializable and/or make some of its fields transient.
  • In the case above, an inner class of ResettableEventBus seems to be not serialisable. It is interesting to notice how the root object being serialised is a VaadinSession. Thanks to the extendedDebugInfo you can follow up the whole serialisation path in the object graph until it throws a java.io.NotSerializableException
Downsides

Unfortunately the report provided by extendedDebugInfo is not a full one, meaning that it stops at the first error encountered. So basically your only option is to fix and start over the process outlined above until no more serialization exceptions show up.

Failed attempts 

Before giving up to the laborious manual process above, I tried several options, including some fancy recursive scripts through the whole object graph using reflections and other magic. But to no avail. You can read about them in my comment to JIRA issue.

 

Finding a way to detect serialization issues during Magnolia build

In this case I came up with a very simple Groovy script 

import org.apache.commons.lang3.SerializationUtils
import com.vaadin.server.VaadinSession
/**
* This script will attempt to serialize a VaadinSession, that is the root object which is 
* usually serialized by a Servlet container when shutting down a session. 
* It will throw a java.io.NotSerializableException if something goes wrong in the serialization process at any point of the object graph.
* The Servlet container should be run with the following JVM option -Dsun.io.serialization.extendedDebugInfo=true 
* in order to have a useful debugging output in case of error.
*/

cl = VaadinSession.class.classLoader
vaadinSession = cl.loadClass('com.vaadin.server.VaadinSession').getCurrent()
SerializationUtils.serialize(vaadinSession)

 

This works fine when run through the Magnolia Groovy Console and will basically output the same stack trace shown above. I thought it could be run as an integration test, like we do for our crawler.groovy. However this does not work, the Groovy Maven plugin being basically disconnected from the Magnolia test instance (two different threads).

ToDo

Find a way to run the script above as an integration test against a real Magnolia instance. One idea could be registering a GroovyTestServlet which will get passed the script source and executes it. Then we assert that the output does not contain java.io.NotSerializableException.

 

 

 

  • No labels