Skip to content
Browse files

ARQ-678 Handle NoClassDefFoundException in ExceptionProxy

In cases where we have the Exception class on classpath, but the Class is refering to a unknown class.
  • Loading branch information...
1 parent 9d3b82f commit 116f59e467dffe40796ba7ff3bce98e49bb477b9 @aslakknutsen aslakknutsen committed
View
156 test/spi/src/main/java/org/jboss/arquillian/test/spi/ExceptionProxy.java
@@ -24,7 +24,6 @@
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
-import java.lang.reflect.Constructor;
/**
* Takes an exception class and creates a proxy that can be used to rebuild the
@@ -118,127 +117,6 @@ public ArquillianProxyException createProxyException(String reason)
}
/**
- * Constructs an instance of the passed in class if a suitable constructor
- * is found. If the constructor subclasses {@link Throwable} it is returned.
- * If a Class instance is not constructed ot is not a {@link Throwable} then
- * another exception is returned indicating this.
- *
- * @param clazz
- * Class to construct
- * @return Instance of the Throwable class.
- */
- private Throwable constructExceptionForClass(Class<?> clazz)
- {
- Object object = buildObjectFromClassConstructors(clazz);
-
- if (object == null)
- {
- return createProxyException("Could not find suitable constructor");
- }
-
- if (!(object instanceof Throwable))
- {
- return createProxyException("Proxy references non-Throwable type");
- }
- return (Throwable) object;
- }
-
- private Object buildObjectFromClassConstructors(Class<?> clazz)
- {
- // try the (String,Throwable) constructor first
- Object object = buildExceptionFromConstructor(clazz, new Class<?>[] {String.class, Throwable.class}, new Object[] {message, getCause()});
- if (object != null)
- {
- return object;
- }
-
- // try the (String,Exception) constructor
- object = buildExceptionFromConstructor(clazz, new Class<?>[] {String.class, Exception.class}, new Object[] {message, getCause()});
- if (object != null)
- {
- return object;
- }
-
- // try the (Throwable) constructor
- object = buildExceptionFromConstructor(clazz, new Class<?>[]{Throwable.class}, new Object[] {getCause()});
- if (object != null)
- {
- return object;
- }
-
- // try the (Exception) constructor
- object = buildExceptionFromConstructor(clazz, new Class<?>[]{Exception.class}, new Object[] {getCause()});
- if (object != null)
- {
- return object;
- }
-
- // try the (Object) constructor
- object = buildExceptionFromConstructor(clazz, new Class<?>[]{Object.class}, new Object[] {message});
- if (object != null)
- {
- return object;
- }
-
- // try the (String, Object) constructor
- object = buildExceptionFromConstructor(clazz, new Class<?>[]{String.class}, new Object[] {message});
- if (object != null)
- {
- return object;
- }
-
- return null;
- }
-
- /**
- * Attempt to build an exception of the given class type using the
- * constructor signature and parameters passed in. If no constructor matches
- * or the constructor throws an exception, then null is returned.
- *
- * @param clazz
- * Class to construct
- * @param signature
- * Array of class types to match the signature on
- * @param params
- * Parameter values to pass to the constructor if found.
- * @return The object instance created using the constructor
- */
- private <T> T buildExceptionFromConstructor(Class<T> clazz, Class<?>[] signature, Object[] params) {
- Constructor<?> constructor = null;
- // try the message,cause constructor first
- Class<?> nextSource = clazz;
-// while (nextSource != Object.class && constructor == null)
-// {
- try
- {
- constructor = nextSource.getDeclaredConstructor(signature);
- }
- catch (SecurityException e)
- {
- // we'll try the next signature
- }
- catch (NoSuchMethodException e)
- {
- // we'll try the next signature
- }
-// nextSource = nextSource.getSuperclass();
-// }
- // if we found a working constructor, use it
- if (constructor != null) {
- try {
- @SuppressWarnings("unchecked")
- T result = (T) constructor.newInstance(params);
- return result;
- } catch (Throwable e) {
- return null;
- }
- }
- // no matching constructor, no result
- return null;
-
- }
-
- /**
* Static method to create an exception proxy for the passed in
* {@link Throwable} class. If null is passed in, null is returned as the
* exception proxy
@@ -302,29 +180,21 @@ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundExcept
try
{
ByteArrayInputStream originalIn = new ByteArrayInputStream(originalExceptionData);
- ObjectInputStream input = new ObjectInputStream(originalIn) ;
- /*// need to active for testing
- {
-
- @Override
- protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException
- {
- return Class.forName(desc.getName(), false, Thread.currentThread().getContextClassLoader());
- }
- };
- */
+ ObjectInputStream input = new ObjectInputStream(originalIn);
+// // Uncomment to run ExceptionProxySerializationTestCase
+// {
+// @Override
+// protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException
+// {
+// return Class.forName(desc.getName(), false, Thread.currentThread().getContextClassLoader());
+// }
+// };
original = (Throwable)input.readObject();
- try
- {
- // reset the cause, so we can de-serialize them individual
- SecurityActions.setFieldValue(Throwable.class, original, "cause", causeProxy.createException());
- }
- catch (Exception e)
- {
- // move on, try to serialize anyway
- }
+
+ // reset the cause, so we can de-serialize them individual
+ SecurityActions.setFieldValue(Throwable.class, original, "cause", causeProxy.createException());
}
- catch (ClassNotFoundException e)
+ catch (Throwable e) // ClassNotFoundExcpetion / NoClassDefFoundError
{
// ignore, could not load class on client side, move on and create a fake 'proxy' later
}
View
8 .../spi/src/test/java/org/jboss/arquillian/test/spi/ExceptionProxySerializationTestCase.java
@@ -38,7 +38,7 @@
public class ExceptionProxySerializationTestCase
{
- @Test @Ignore // not ready for automation
+ @Test @Ignore // not ready for automation, uncomment ObjectInputStream override in ExceptionProxy.readExternal to run
public void shouldBeAbleToDeserialize() throws Exception
{
ByteArrayOutputStream output = new ByteArrayOutputStream();
@@ -66,10 +66,14 @@ public void shouldBeAbleToDeserialize() throws Exception
@Override
protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
{
- if(UnknownException.class.getName().equals(name))
+ if(UnknownException.class.getName().equals(name))
{
return null;
}
+ if(UnknownObject.class.getName().equals(name))
+ {
+ throw new NoClassDefFoundError(name);
+ }
return super.loadClass(name, resolve);
}
};
View
1 test/spi/src/test/java/org/jboss/arquillian/test/spi/ExceptionProxyTestCase.java
@@ -60,6 +60,7 @@ private void proxy(Throwable throwable) throws Throwable
/**
* @param throwable
*/
+ @SuppressWarnings("unused")
private void printConstructors(Throwable throwable) throws Exception
{
System.out.println("Declared-Constrcutors for: " + throwable.getClass());
View
4 test/spi/src/test/java/org/jboss/arquillian/test/spi/UnknownException.java
@@ -25,8 +25,8 @@
*/
public class UnknownException extends Exception
{
- private static final long serialVersionUID = 1L;
-
+ private static final UnknownObject serialVersionUID = new UnknownObject();
+
public UnknownException(Throwable cause)
{
super(cause);
View
31 test/spi/src/test/java/org/jboss/arquillian/test/spi/UnknownObject.java
@@ -0,0 +1,31 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @authors tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.arquillian.test.spi;
+
+import java.io.Serializable;
+
+/**
+ * UnknownObject
+ *
+ * @author <a href="mailto:aslak@redhat.com">Aslak Knutsen</a>
+ * @version $Revision: $
+ */
+public class UnknownObject implements Serializable
+{
+
+}

0 comments on commit 116f59e

Please sign in to comment.
Something went wrong with that request. Please try again.