Class ExceptionProxy

java.lang.Object
org.jboss.arquillian.test.spi.ExceptionProxy
All Implemented Interfaces:
Externalizable, Serializable

public class ExceptionProxy extends Object implements Externalizable
Takes an exception class and creates a proxy that can be used to rebuild the exception. The problem stems from problems serializing exceptions and deserializing them in another application where the exception classes might not exist, or they might exist in different version. This proxy also propagates the stacktrace and the cause exception to create totally portable exceptions.

This class creates a serializable proxy of the exception and when unserialized can be used to re-create the exception based on the following rules :
  • If the exception class exists on the client, the original exception is created
  • If the exception class exists, but doesn't have a suitable constructor then another exception is thrown referencing the original exception
  • If the exception class doesn't exist, one of its superclasses is used
Author:
Andy Gibson
See Also:
  • Constructor Details

    • ExceptionProxy

      public ExceptionProxy()
    • ExceptionProxy

      public ExceptionProxy(Throwable throwable)
  • Method Details

    • createForException

      public static ExceptionProxy createForException(Throwable throwable)
      Static method to create an exception proxy for the passed in Throwable class. If null is passed in, null is returned as the exception proxy
      Parameters:
      throwable - Exception to proxy
      Returns:
      An ExceptionProxy representing the exception passed in
    • hasException

      public boolean hasException()
      Indicates whether this proxy wraps an exception
      Returns:
      Flag indicating an exception is wrapped.
    • createException

      public Throwable createException()
      Constructs an instance of the proxied exception based on the class name, message, stack trace and if applicable, and the cause if the cause could be deserialized in the client. Otherwise, this returns an ArquillianProxyException
      Returns:
      The constructed Throwable instance if one exists, null otherwise
    • createProxyException

      public ArquillianProxyException createProxyException(String reason)
    • getCause

      public Throwable getCause()
      Returns the cause of the exception represented by this proxy
      Returns:
      The cause of this exception
    • getClassName

      public String getClassName()
    • getMessage

      public String getMessage()
    • getTrace

      public StackTraceElement[] getTrace()
    • getCauseProxy

      public ExceptionProxy getCauseProxy()
    • getOriginal

      public Throwable getOriginal()
    • getSerializationProcessException

      public Throwable getSerializationProcessException()
    • getVersion

      public ExceptionProxy.Version getVersion()
    • getExceptionHierarchy

      public List<String> getExceptionHierarchy()
    • toString

      public String toString()
      Override to provide the full details of the exception being proxied
      Overrides:
      toString in class Object
      Returns:
      The full details of the exception being proxied
    • readExternal

      public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
      Custom Serialization logic.

      If possible, we try to keep the original Exception form the Container side.

      If we can't load the Exception on the client side, return a ArquillianProxyException that keeps the original stack trace etc.

      We can't use in.readObject() on the Throwable cause, because if a ClassNotFoundException is thrown, the stream is marked with the exception and that stream is the same stream that is deserializing us, so we will fail outside of our control. Store the Throwable cause as a serialized byte array instead, so we can deserialize it outside of our own stream.

      Specified by:
      readExternal in interface Externalizable
      Throws:
      IOException
      ClassNotFoundException
    • writeExternal

      public void writeExternal(ObjectOutput out) throws IOException
      Specified by:
      writeExternal in interface Externalizable
      Throws:
      IOException
    • getExceptionHierarchy

      protected List<String> getExceptionHierarchy(Throwable t)
      Get the exception hierarchy for the exception class being proxied.
      Returns:
      list of exception types in the hierarchy
    • buildOriginalException

      protected Throwable buildOriginalException()
      Build the original exception based on the exception class name. This first tries to use a ctor with a message, then a default ctor.
      Returns:
      the original exception