java.io.NotSerializableException Error weblogic

Oracle Weblogic Server
####<Feb 9, 2012 8:48:09 AM GMT> <Error> <Cluster> <corp.techpaste.com> <techpaste-ManagedServer1> <ACTIVE ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<anonymous>> <1328777289869> <BEA-000126> <All session objects should be serializable to replicate. Check the objects in your session. Failed to replicate non-serializable object.

java.rmi.MarshalException: failed to marshal create(Lweblogic.rmi.spi.HostID;ILweblogic.cluster.replication.ROID;Lweblogic.cluster.replication.Replicatable;); nested exception is:

java.io.NotSerializableException: java.util.AbstractList$SubAbstractListRandomAccess

at weblogic.rjvm.BasicOutboundRequest.marshalArgs(BasicOutboundRequest.java:90)

at weblogic.rmi.internal.BasicRemoteRef.invoke(BasicRemoteRef.java:221)

at weblogic.cluster.replication.ReplicationManager_1032_WLStub.create(Unknown Source)

at sun.reflect.GeneratedMethodAccessor441.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:600) at weblogic.cluster.replication.SecureReplicationInvocationHandler$ReplicationServicesInvocationAction.run(SecureReplicationInvocationHandler.java:184)

at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)

at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)

at weblogic.cluster.replication.SecureReplicationInvocationHandler.invoke(SecureReplicationInvocationHandler.java:154)

at $Proxy59.create(Unknown Source)

at weblogic.cluster.replication.ReplicationManager.trySecondary(ReplicationManager.java:685)

at weblogic.cluster.replication.ReplicationManager.createSecondary(ReplicationManager.java:649)

at weblogic.cluster.replication.ReplicationManager.getPrimary(ReplicationManager.java:629)

at weblogic.cluster.replication.ReplicationManager.lookup(ReplicationManager.java:368)

at weblogic.servlet.internal.session.ReplicatedSessionContext.getSessionInternal(ReplicatedSessionContext.java:382)

at weblogic.servlet.internal.session.ReplicatedSessionContext.getSessionInternal(ReplicatedSessionContext.java:239)

at weblogic.servlet.internal.ServletRequestImpl$SessionHelper.getValidSession(ServletRequestImpl.java:2776)

at weblogic.servlet.internal.ServletRequestImpl$SessionHelper.getSessionInternal(ServletRequestImpl.java:2299)

at weblogic.servlet.internal.ServletRequestImpl$SessionHelper.getSession(ServletRequestImpl.java:2266)

at weblogic.servlet.internal.ServletRequestImpl.getSession(ServletRequestImpl.java:1272)

at weblogic.servlet.security.internal.SecurityModule$SessionRetrievalAction.run(SecurityModule.java:610)

at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)

at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)

at weblogic.servlet.security.internal.SecurityModule.getUserSession(SecurityModule.java:501)

at weblogic.servlet.security.internal.ServletSecurityManager.checkAccess(ServletSecurityManager.java:61)

at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2138)

at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2108)

at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1432)

at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)

at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)

This error comes when the deployed application session contains a non-serializable object (specifically a List obtained by calling subList() on another List).

Application code should get reviewed to identify this object and remove it or replace it with a serializable object – e.g. copy its contents into an ArrayList and store that instead.

To support in-memory replication of HTTP session states, all servlet and JSP session data must be serializable.

Serialization is the process of converting a complex data structure, such as a parallel arrangement of data (in which a number of bits are transmitted at a time along parallel channels) into a serial form (in which one bit at a time is transmitted); a serial interface provides this conversion to enable data transmission.

Every field in an object must be serializable or transient in order for the object to be considered serializable. If the servlet or JSP uses a combination of serializable and non-serializable objects, WebLogic Server does not replicate the session state of the non-serializable objects.

To check which objects are serilazable or not we can follow below steps:
Below JSP page tests serializing all the objects and gives a good output page showing this information.

Put this in your web application and hit the JSP like so:

http://localhost/myWebApplication/SerTestServlet.jsp

The output will contain this information (nicely formatted in the browser) and show the attribute name and the class name. It would be a good test to have in your staging application (you can always remove the JSP at any time very easily).

# Attribute Name Class Name Serializable Serializes Okay No args C'TOR Bytes
0 simplesession.servername java.lang.String Yes Yes Yes 15
1 sessiontest.counter java.lang.Integer Yes Yes No 81
2 serialize_obj demo.SessionReplicate.serize Yes Yes No 94
3 noserize_obj demo.SessionReplicate.noserize No n/a No 94

The total size of the objects in the HTTPSession is 190 bytes (non-serializable doesn’t count)

It can be placed under any web-application in the top level directory as in the following example, where myWebApplication is the top-level of the war or exploded app:

myWebApplication
SerTestServlet.jsp
WEB-INF
web.xml
weblogic.xml
images
index.jsp

SerTestServlet.jsp

<!doctype html public "-//w3c/dtd HTML 4.0//en">
<%@ page import="java.util.*"%>
<%@ page import="java.io.*"%>
<%@ page import="java.lang.reflect.*" %>

<html>
<head><title>Clusterable Session Object Test</title></head>
<body bgcolor="#FFFFFF">
<p>
<font face="Helvetica">

<h2>
<font color=#DB1260>
Check Clusterable Session Objects
</font>
</h2>

<p>This jsp tests whether the attributes held in the current HTTP session are serialisable.
In order for web-applications to be capable of being replicated using WebLogic's in-memory clustering,
all session attributes must be serialisable.</p>
<p>
<p>Therefore the object's class must implement the <font face="Courier">java.io.Serializable</font> interface.
However, simply declaring that a class implements this interface is not sufficient and can often lead
to problems when trying to cluster a web application for the first time. This JSP can be used to help
diagnose such problems more quickly.</p>
<p>
<p>In order to guarantee that the session is truely serialisable this page tests each session attribute
by actually attempting to serialise it.
</p>

</p>

<br>

<%
boolean clusterable= true;
int attrNum= 0;
ByteArrayOutputStream baos = null;
ObjectOutputStream oos = null;
byte[] array = null;
ByteArrayInputStream bais = null;
ObjectInputStream ois = null;
Object deserializedObj = null;
String attrName= null;
Object attrValue= null;
String impSerStr= null;
String doesSerStr= null;
String pctor = null;
int size = 0;
int totalSize = 0;
Enumeration attrs = pageContext.getAttributeNamesInScope (pageContext.SESSION_SCOPE);
%>
<center>
<table border=1 cellspacing=2 cellpadding=5 bgcolor=#EEEEEE>
<tr>
<th>#</th>
<th>Attribute Name</th>
<th>Class Name</th>
<th>Serializable</th>
<th>Serialises Okay</th>
<th>No args C'TOR</th>
<th>Bytes</th>
</tr>
<%
while (attrs.hasMoreElements())
{
attrName= (String)attrs.nextElement();
attrValue= pageContext.getAttribute (attrName, pageContext.SESSION_SCOPE);
if (attrValue instanceof Serializable)
{
impSerStr= "Yes";
doesSerStr= "Yes";

pctor="<font color=\"red\"><b>No</b></font>";

try
{
baos = new ByteArrayOutputStream (2048);
oos = new ObjectOutputStream (baos);
oos.writeObject (attrValue);
oos.flush();
array = baos.toByteArray();
bais = new ByteArrayInputStream (array);
ois = new ObjectInputStream (bais);
deserializedObj = ois.readObject();

/* Public contstructor check */
Constructor[] ctors = deserializedObj.getClass().getConstructors();
for (int i=0; i< ctors.length; i++) {
if ( ( (Constructor) ctors[i]).getParameterTypes().length == 0) {
pctor="Yes";
}
}

if (!pctor.equalsIgnoreCase("Yes")) {
clusterable=false;
}

size = array.length;
totalSize += size;
}
catch (NotSerializableException nse)
{
doesSerStr= "<font color=\"red\">No </font><i>(See stack trace on console)</i>";
clusterable= false;
application.log("serTest.jsp DIAG: Attribute #" + attrNum + " failed to serialise: Name=" + attrName +
", Class=" + attrValue.getClass().getName() + " - " + nse.getMessage() + " ...");
nse.printStackTrace();
}
catch (Exception e)
{
doesSerStr= "<i><b>Error:</b>&nbsp;<font size=-1>" + e.getMessage() +"</font></i>";
clusterable= false;
application.log("serTest.jsp DIAG: Attribute #" + attrNum + " unexpected failure: Name=" + attrName +
", Class=" + attrValue.getClass().getName() + " - " + e.getMessage());
e.printStackTrace();
}
}
else
{
clusterable= false;
impSerStr= "<font color=\"red\"><b>No</b></font>";
doesSerStr= "<i>n/a</i>";
}
%>
<tr>
<td><%=attrNum++ %></td>
<td><%=attrName%></td>
<td><%=attrValue.getClass().getName()%></td>
<td><%=impSerStr%></td>
<td><%=doesSerStr%></td>
<td><font size="-2"><%=pctor%></font></td>
<td><%=size%></td>
</tr>

<%
}
%>
</table>
<br>
<%
if (clusterable)
{
%>
<font size="+2" color="blue">Your HTTP session supports clustering</font>
<%
}
else
{
%>
<font size="+2" color="red"></font>
<%
}

long mbConv = 1048576;

%>
<br>
<p>The total size of the objects in the HTTPSession is <%= totalSize %> bytes</p>

<h3>Runtime Data</h3>
<table border=1 cellspacing=2 cellpadding=5 bgcolor=#EEEEEE>
<tr><td align="left">The memory in use</td><td><%= ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / mbConv) %> Mb</td></tr>
<tr><td align="left">The current free memory</td><td><%= Runtime.getRuntime().freeMemory() / mbConv %> Mb</td></tr>
<tr><td align="left">The total memory currently allocated</td><td><%= Runtime.getRuntime().totalMemory() / mbConv %> Mb</td></tr>
<tr><td align="left">The maximum memory available</td><td><%= Runtime.getRuntime().maxMemory() / mbConv %> Mb</td></tr>
<tr><td align="left">CPU Count</td><td><%= Runtime.getRuntime().availableProcessors() %></td></tr>
</table>
<hr>
</center>
<p>
<font size=-1>Copyright &copy; 2012.</font>
</body>
</html>

 

By using above JSP file we can determine the Non-Serializable objects and fix them in code by dev team to make the session replication possible.

In case of any ©Copyright or missing credits issue please check CopyRights page for faster resolutions.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.