/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.client.util;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
import org.teiid.client.SourceWarning;
import org.teiid.core.TeiidException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.TeiidRuntimeException;
import org.teiid.core.util.ReflectionHelper;
import org.teiid.core.util.UnitTestUtil;
@SuppressWarnings("nls")
public class TestExceptionHolder {
private static final class CustomStream extends ObjectOutputStream {
final AtomicInteger count = new AtomicInteger();
private CustomStream(OutputStream out)
throws IOException {
super(out);
this.enableReplaceObject(true);
}
@Override
protected Object replaceObject(Object obj) throws IOException {
if (obj instanceof ExceptionHolder) {
count.incrementAndGet();
}
return super.replaceObject(obj);
}
}
@SuppressWarnings("all")
public static class BadException extends TeiidProcessingException {
private Object obj;
public BadException(String msg) {super(msg);}
public BadException(Object obj) {
this.obj = obj;
}
}
@Test public void testDeserializationUnknownException() throws Exception {
ClassLoader cl = new URLClassLoader(new URL[] {UnitTestUtil.getTestDataFile("test.jar").toURI().toURL()}); //$NON-NLS-1$
Object obj = ReflectionHelper.create("test.Test", null, cl); //$NON-NLS-1$
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(new ExceptionHolder(new BadException(obj)));
oos.flush();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
ExceptionHolder holder = (ExceptionHolder)ois.readObject();
assertTrue(holder.getException() instanceof BadException);
assertEquals("Remote org.teiid.client.util.TestExceptionHolder$BadException: null", holder.getException().getMessage()); //$NON-NLS-1$
}
@SuppressWarnings("all")
public static class BadException2 extends TeiidProcessingException {
public BadException2(String msg) {
super(msg);
}
public BadException2(Throwable e, String msg) {
super(e, msg);
}
}
@Test public void testDeserializationUnknownChildException() throws Exception {
ClassLoader cl = new URLClassLoader(new URL[] {UnitTestUtil.getTestDataFile("test.jar").toURI().toURL()}); //$NON-NLS-1$
Exception obj = (Exception)ReflectionHelper.create("test.UnknownException", null, cl); //$NON-NLS-1$
obj.initCause(new SQLException("something bad happended")); //$NON-NLS-1$
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(new ExceptionHolder(new BadException2(obj, "I have foreign exception embedded in me"))); //$NON-NLS-1$
oos.flush();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
ExceptionHolder holder = (ExceptionHolder)ois.readObject();
Throwable e = holder.getException();
assertTrue(e instanceof BadException2);
assertEquals("Remote org.teiid.client.util.TestExceptionHolder$BadException2: I have foreign exception embedded in me", e.getMessage()); //$NON-NLS-1$
e = e.getCause();
assertTrue(e instanceof TeiidRuntimeException);
e = e.getCause();
assertTrue(e instanceof SQLException);
assertEquals("Remote java.sql.SQLException: something bad happended", e.getMessage()); //$NON-NLS-1$
}
@Test public void testSQLExceptionChain() throws Exception {
ClassLoader cl = new URLClassLoader(new URL[] {UnitTestUtil.getTestDataFile("test.jar").toURI().toURL()}); //$NON-NLS-1$
Exception obj = (Exception)ReflectionHelper.create("test.UnknownException", null, cl); //$NON-NLS-1$
SQLException se = new SQLException("something bad happened");
se.initCause(obj); //$NON-NLS-1$
SQLException next = se;
for (int i = 0; i < 10; i++) {
SQLException se1 = new SQLException("something else bad happened");
se1.initCause(obj); //$NON-NLS-1$
next.setNextException(se1);
next = se1;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
CustomStream oos = new CustomStream(baos);
oos.writeObject(new ExceptionHolder(se, false)); //$NON-NLS-1$
oos.flush();
assertEquals(22, oos.count.get());
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
ExceptionHolder holder = (ExceptionHolder)ois.readObject();
Throwable e = holder.getException();
assertTrue(e instanceof SQLException);
assertEquals("Remote java.sql.SQLException: something bad happened", e.getMessage()); //$NON-NLS-1$
assertTrue(e.getCause() instanceof TeiidRuntimeException);
e = ((SQLException)e).getNextException();
assertTrue(e instanceof SQLException);
assertEquals("Remote java.sql.SQLException: something else bad happened", e.getMessage()); //$NON-NLS-1$
int count = 0;
while ((e = ((SQLException)e).getNextException()) != null) {
count++;
}
assertEquals(9, count);
}
@Test public void testDeserializationUnknownChildException2() throws Exception {
ClassLoader cl = new URLClassLoader(new URL[] {UnitTestUtil.getTestDataFile("test.jar").toURI().toURL()}); //$NON-NLS-1$
ArrayList<String> args = new ArrayList<String>();
args.add("Unknown Exception"); //$NON-NLS-1$
Exception obj = (Exception)ReflectionHelper.create("test.UnknownException", args, cl); //$NON-NLS-1$
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(new ExceptionHolder(obj));
oos.flush();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
ExceptionHolder holder = (ExceptionHolder)ois.readObject();
Throwable e = holder.getException();
assertTrue(e instanceof TeiidRuntimeException);
assertEquals("Remote test.UnknownException: Unknown Exception", e.getMessage()); //$NON-NLS-1$
}
private static class NotSerializable {
}
@Test public void testDeserializationNotSerializable() throws Exception {
Exception ex = new TeiidException() {
NotSerializable ns = new NotSerializable();
};
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(new ExceptionHolder(ex));
oos.flush();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
ExceptionHolder holder = (ExceptionHolder)ois.readObject();
Throwable e = holder.getException();
assertTrue(e instanceof TeiidException);
}
@Test public void testSourceWarning() throws Exception {
ClassLoader cl = new URLClassLoader(new URL[] {UnitTestUtil.getTestDataFile("test.jar").toURI().toURL()}); //$NON-NLS-1$
ArrayList<String> args = new ArrayList<String>();
args.add("Unknown Exception"); //$NON-NLS-1$
Exception obj = (Exception)ReflectionHelper.create("test.UnknownException", args, cl); //$NON-NLS-1$
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(new ExceptionHolder(new SourceWarning("x", "y", obj, true)));
oos.flush();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
ExceptionHolder holder = (ExceptionHolder)ois.readObject();
SourceWarning sw = (SourceWarning)holder.getException();
assertEquals(sw.getConnectorBindingName(), "y");
assertEquals(sw.getModelName(), "x");
assertTrue(sw.isPartialResultsError());
try {
ois = new ObjectInputStream(new FileInputStream(UnitTestUtil.getTestDataFile("old-exceptionholder.ser")));
holder = (ExceptionHolder)ois.readObject();
assertTrue(holder.getException() instanceof TeiidException);
} finally {
ois.close();
}
}
}