[infinispan-commits] Infinispan SVN: r858 - in trunk/core/src: test/java/org/infinispan/marshall and 1 other directory.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Fri Sep 25 10:35:59 EDT 2009


Author: galder.zamarreno at jboss.com
Date: 2009-09-25 10:35:59 -0400 (Fri, 25 Sep 2009)
New Revision: 858

Modified:
   trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java
   trunk/core/src/test/java/org/infinispan/marshall/VersionAwareMarshallerTest.java
Log:
[ISPN-155] (Marshalling code to provide more helpful stacktraces) Done.

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java	2009-09-25 14:04:32 UTC (rev 857)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/JBossMarshaller.java	2009-09-25 14:35:59 UTC (rev 858)
@@ -30,9 +30,11 @@
 import org.infinispan.util.logging.Log;
 import org.infinispan.util.logging.LogFactory;
 import org.jboss.marshalling.ContextClassResolver;
+import org.jboss.marshalling.ExceptionListener;
 import org.jboss.marshalling.MarshallerFactory;
 import org.jboss.marshalling.Marshalling;
 import org.jboss.marshalling.MarshallingConfiguration;
+import org.jboss.marshalling.TraceInformation;
 import org.jboss.marshalling.Unmarshaller;
 import org.jboss.marshalling.reflect.SunReflectiveCreator;
 
@@ -42,6 +44,8 @@
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.io.OutputStream;
+import java.lang.reflect.Method;
+import java.net.URL;
 
 /**
  * JBossMarshaller.
@@ -95,7 +99,6 @@
       log.debug("Using JBoss Marshalling based marshaller.");
       this.defaultCl = defaultCl;
       try {
-         // TODO: Enable different marshaller factories via configuration
          factory = (MarshallerFactory) Util.getInstance(DEFAULT_MARSHALLER_FACTORY);
       } catch (Exception e) {
          throw new CacheException("Unable to load JBoss Marshalling marshaller factory " + DEFAULT_MARSHALLER_FACTORY, e);
@@ -105,7 +108,7 @@
       configuration = new MarshallingConfiguration();
       configuration.setCreator(new SunReflectiveCreator());
       configuration.setObjectTable(objectTable);
-      
+      configuration.setExceptionListener(new DebuggingExceptionListener());
       // ContextClassResolver provides same functionality as MarshalledValueInputStream
       configuration.setClassResolver(new ContextClassResolver());
    }
@@ -211,4 +214,55 @@
       objectTable.start(cmdFactory, ispnMarshaller);
       return objectTable;
    }
+
+   private static class DebuggingExceptionListener implements ExceptionListener {
+
+      public void handleMarshallingException(Throwable problem, Object subject) {
+         if (log.isDebugEnabled()) {
+            TraceInformation.addUserInformation(problem, "toString = " + subject.toString());
+         }
+      }
+
+      public void handleUnmarshallingException(Throwable problem, Class<?> subjectClass) {
+         if (log.isDebugEnabled()) {
+            StringBuilder builder = new StringBuilder();
+            ClassLoader cl = subjectClass.getClassLoader();
+            builder.append("classloader hierarchy:");
+            ClassLoader parent = cl;
+            while( parent != null ) {
+               if (parent.equals(cl)) {
+                  builder.append("\n\t\t-> type classloader = " + parent);
+               } else {
+                  builder.append("\n\t\t-> parent classloader = " + parent);
+               }
+               URL[] urls = getClassLoaderURLs(parent);
+               int length = urls != null ? urls.length : 0;
+               for(int u = 0; u < length; u ++) {
+                  builder.append("\n\t\t->..."+urls[u]);
+               }
+               if( parent != null ) parent = parent.getParent();
+            }
+            TraceInformation.addUserInformation(problem, builder.toString());
+         }
+      }
+
+      public void handleUnmarshallingException(Throwable problem) {
+         // no-op
+      }
+      
+      private static URL[] getClassLoaderURLs(ClassLoader cl) {
+         URL[] urls = {};
+         try {
+            Class returnType = urls.getClass();
+            Class[] parameterTypes = {};
+            Method getURLs = cl.getClass().getMethod("getURLs", parameterTypes);
+            if( returnType.isAssignableFrom(getURLs.getReturnType()) ) {
+               Object[] args = {};
+               urls = (URL[]) getURLs.invoke(cl, args);
+            }
+         } catch(Exception ignore) {}
+         return urls;
+      }
+
+   }
 }

Modified: trunk/core/src/test/java/org/infinispan/marshall/VersionAwareMarshallerTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/marshall/VersionAwareMarshallerTest.java	2009-09-25 14:04:32 UTC (rev 857)
+++ trunk/core/src/test/java/org/infinispan/marshall/VersionAwareMarshallerTest.java	2009-09-25 14:35:59 UTC (rev 858)
@@ -72,6 +72,7 @@
 import org.infinispan.util.concurrent.TimeoutException;
 import org.infinispan.util.logging.Log;
 import org.infinispan.util.logging.LogFactory;
+import org.jboss.marshalling.TraceInformation;
 import org.jgroups.stack.IpAddress;
 import org.testng.annotations.AfterTest;
 import org.testng.annotations.BeforeTest;
@@ -79,6 +80,7 @@
 
 import java.io.Externalizable;
 import java.io.IOException;
+import java.io.NotSerializableException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.util.*;
@@ -419,7 +421,49 @@
       assert rEntry.contentType.equals(entry.contentType);
       assert rEntry.lastModified == entry.lastModified;
    }
+
+   public void testNestedNonSerializable() throws Exception {
+      PutKeyValueCommand cmd = new PutKeyValueCommand("k", new Object(), false, null, 0, 0);
+      try {
+         marshaller.objectToByteBuffer(cmd);
+      } catch (NotSerializableException e) {
+         log.info("Log exception for output format verification", e);
+         TraceInformation inf = (TraceInformation) e.getCause();
+         assert inf.toString().contains("in object java.lang.Object@");
+         assert inf.toString().contains("in object org.infinispan.commands.write.PutKeyValueCommand@");
+      }
+   }
+
+   public void testNonSerializable() throws Exception {
+      try {
+         marshaller.objectToByteBuffer(new Object());
+      } catch (NotSerializableException e) {
+         log.info("Log exception for output format verification", e);
+         TraceInformation inf = (TraceInformation) e.getCause();
+         assert inf.toString().contains("in object java.lang.Object@");
+      }
+      
+   }
    
+   public void testErrorUnmarshalling() throws Exception {
+      Pojo pojo = new Pojo() {
+         @Override
+         public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+            throw new IOException("Injected failue!");
+         }
+         
+      };
+      byte[] bytes = marshaller.objectToByteBuffer(pojo);
+      try {
+         marshaller.objectFromByteBuffer(bytes);
+      } catch (IOException e) {
+         log.info("Log exception for output format verification", e);
+         TraceInformation inf = (TraceInformation) e.getCause();
+         assert inf.toString().contains("in object of type org.infinispan.marshall.VersionAwareMarshallerTest$1");
+      }
+      
+   }
+   
    protected void marshallAndAssertEquality(Object writeObj) throws Exception {
       byte[] bytes = marshaller.objectToByteBuffer(writeObj);
       Object readObj = marshaller.objectFromByteBuffer(bytes);



More information about the infinispan-commits mailing list