Author: shawkins
Date: 2012-04-19 13:44:05 -0400 (Thu, 19 Apr 2012)
New Revision: 4021
Modified:
branches/8.0.x/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
branches/8.0.x/client/src/main/java/org/teiid/client/util/ExceptionHolder.java
branches/8.0.x/client/src/main/java/org/teiid/jdbc/TeiidSQLWarning.java
branches/8.0.x/client/src/test/java/org/teiid/client/util/TestExceptionHolder.java
branches/8.0.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCBaseExecution.java
Log:
TEIID-2007 updating the ExceptionHolder to handle SQLException chains and correcting the
JDBC handling of warnings
Modified: branches/8.0.x/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
===================================================================
--- branches/8.0.x/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html 2012-04-18
18:03:49 UTC (rev 4020)
+++ branches/8.0.x/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html 2012-04-19
17:44:05 UTC (rev 4021)
@@ -80,6 +80,8 @@
<h4>from 7.7</h4>
<ul>
<li>parse/formatdate and parse/formattime are no longer pushdown functions. They
are converted into parse/formattimestamp.
+ <li>SQLWarning exception chains attached to the ExecutionContext will be returned
as a single TeiidSQLWarning rather than as individual TeiidSQLWarnings. See the
TeiidSQLWarning javadocs
+for how to access the underlying SQLWarning chains.
</ul>
<h4>from 7.5</h4>
Modified: branches/8.0.x/client/src/main/java/org/teiid/client/util/ExceptionHolder.java
===================================================================
---
branches/8.0.x/client/src/main/java/org/teiid/client/util/ExceptionHolder.java 2012-04-18
18:03:49 UTC (rev 4020)
+++
branches/8.0.x/client/src/main/java/org/teiid/client/util/ExceptionHolder.java 2012-04-19
17:44:05 UTC (rev 4021)
@@ -22,14 +22,8 @@
package org.teiid.client.util;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutput;
-import java.io.ObjectOutputStream;
+import java.io.*;
+import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -72,23 +66,27 @@
if (this.exception == null) {
Throwable t = buildException(classNames, message, stackTrace, code);
- if (t == null) {
- if (causeHolder != null) {
- this.exception = causeHolder.exception;
- }
+ if (causeHolder != null) {
+ t.initCause(causeHolder.exception);
}
- else {
- if (causeHolder != null) {
- t.initCause(causeHolder.exception);
+ this.exception = t;
+
+ if (this.exception instanceof SQLException) {
+ try {
+ int count = in.readInt();
+ for (int i = 0; i < count; i++) {
+ ExceptionHolder next = (ExceptionHolder)in.readObject();
+ if (next.exception instanceof SQLException) {
+ ((SQLException)this.exception).setNextException((SQLException) next.exception);
+ }
+ }
+ } catch (EOFException e) {
+
+ } catch (OptionalDataException e) {
+
}
- this.exception = t;
}
}
-
- if (this.exception == null) {
- this.exception = new TeiidRuntimeException(message);
- this.exception.setStackTrace(stackTrace);
- }
}
@Override
@@ -126,6 +124,22 @@
else {
out.writeObject(null);
}
+ // handle SQLException chains
+ if (exception instanceof SQLException) {
+ SQLException se = (SQLException)exception;
+ SQLException next = se.getNextException();
+ int count = 0;
+ while (next != null) {
+ count++;
+ next = next.getNextException();
+ }
+ out.writeInt(count);
+ next = se.getNextException();
+ while (next != null) {
+ out.writeObject(new ExceptionHolder(next, true));
+ next = next.getNextException();
+ }
+ }
}
public Throwable getException() {
@@ -133,30 +147,32 @@
}
private Throwable buildException(List<String> classNames, String message,
StackTraceElement[] stackTrace, String code) {
- if (classNames.isEmpty()) {
- return null;
+ String originalClass = Exception.class.getName();
+
+ if (!classNames.isEmpty()) {
+ originalClass = classNames.get(0);
}
- String originalClass = classNames.get(0);
-
List<String> args =
Arrays.asList(CorePlugin.Util.getString("ExceptionHolder.converted_exception",
message, originalClass)); //$NON-NLS-1$
Throwable result = null;
for (String className : classNames) {
try {
result = (Throwable)ReflectionHelper.create(className, args,
ExceptionHolder.class.getClassLoader());
- result.setStackTrace(stackTrace);
break;
} catch (TeiidException e1) {
//
}
}
- if (result instanceof TeiidException) {
+ if (result == null) {
+ result = new TeiidRuntimeException(args.get(0));
+ } else if (result instanceof TeiidException) {
((TeiidException)result).setCode(code);
((TeiidException)result).setOriginalType(classNames.get(0));
}
+ result.setStackTrace(stackTrace);
return result;
}
Modified: branches/8.0.x/client/src/main/java/org/teiid/jdbc/TeiidSQLWarning.java
===================================================================
--- branches/8.0.x/client/src/main/java/org/teiid/jdbc/TeiidSQLWarning.java 2012-04-18
18:03:49 UTC (rev 4020)
+++ branches/8.0.x/client/src/main/java/org/teiid/jdbc/TeiidSQLWarning.java 2012-04-19
17:44:05 UTC (rev 4021)
@@ -26,11 +26,33 @@
/**
- * Teiid specific SQLWarning
+ * Teiid specific SQLWarning<br>
+ * If the cause was a source SQLWarning, then you may need to consult
+ * the warning chain to get all warnings, see the example below.
+ *
+<code><pre>
+//warning will be an instanceof TeiidSQLWarning to convey model/source information
+SQLWarning warning = stmt.getWarnings();
+
+while (warning != null) {
+ Exception e = warning.getCause();
+ if (cause instanceof SQLWarning) {
+ //childWarning should now be the head of the source warning chain
+ SQLWarning childWarning = (SQLWarning)cause;
+ while (childWarning != null) {
+ //do something with childWarning
+ childWarning = childWarning.getNextWarning();
+ }
+ }
+ warning = warning.getNextWarning();
+}
+</pre></code>
+ *
*/
-
public class TeiidSQLWarning extends SQLWarning {
+ private static final long serialVersionUID = -7080782561220818997L;
+
private String modelName = "UNKNOWN"; // variable stores the name of the model
for the atomic query //$NON-NLS-1$
private String sourceName = "UNKNOWN"; // variable stores name of the
connector binding //$NON-NLS-1$
Modified:
branches/8.0.x/client/src/test/java/org/teiid/client/util/TestExceptionHolder.java
===================================================================
---
branches/8.0.x/client/src/test/java/org/teiid/client/util/TestExceptionHolder.java 2012-04-18
18:03:49 UTC (rev 4020)
+++
branches/8.0.x/client/src/test/java/org/teiid/client/util/TestExceptionHolder.java 2012-04-19
17:44:05 UTC (rev 4021)
@@ -1,3 +1,25 @@
+/*
+ * 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.*;
@@ -18,7 +40,7 @@
import org.teiid.core.util.ReflectionHelper;
import org.teiid.core.util.UnitTestUtil;
-
+@SuppressWarnings("nls")
public class TestExceptionHolder {
@SuppressWarnings("all")
@@ -72,12 +94,43 @@
assertTrue(e instanceof BadException2);
assertEquals("Remote
org.teiid.client.util.TestExceptionHolder$BadException2: I have foreign exception embedded
in me", e.getMessage()); //$NON-NLS-1$
- // now unknown exception is not found, so promote known SQL exception up
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 happended");
+ se.initCause(obj); //$NON-NLS-1$
+ SQLException se1 = new SQLException("something else bad happended");
+ se1.initCause(obj); //$NON-NLS-1$
+ se.setNextException(se1);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(new ExceptionHolder(se, false)); //$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 SQLException);
+ assertEquals("Remote java.sql.SQLException: something bad happended",
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
happended", e.getMessage()); //$NON-NLS-1$
+ }
+
@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>();
@@ -93,7 +146,7 @@
ExceptionHolder holder = (ExceptionHolder)ois.readObject();
Throwable e = holder.getException();
assertTrue(e instanceof TeiidRuntimeException);
- assertEquals("Unknown Exception", e.getMessage()); //$NON-NLS-1$
+ assertEquals("Remote test.UnknownException: Unknown Exception",
e.getMessage()); //$NON-NLS-1$
}
private static class NotSerializable {
Modified:
branches/8.0.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCBaseExecution.java
===================================================================
---
branches/8.0.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCBaseExecution.java 2012-04-18
18:03:49 UTC (rev 4020)
+++
branches/8.0.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/JDBCBaseExecution.java 2012-04-19
17:44:05 UTC (rev 4021)
@@ -193,15 +193,15 @@
public void addStatementWarnings() throws SQLException {
SQLWarning warning = this.statement.getWarnings();
- while (warning != null) {
- SQLWarning toAdd = warning;
- warning = toAdd.getNextWarning();
- toAdd.setNextException(null);
- if (LogManager.isMessageToBeRecorded(LogConstants.CTX_CONNECTOR,
MessageLevel.DETAIL)) {
- LogManager.logDetail(LogConstants.CTX_CONNECTOR, context.getRequestId() + "
Warning: ", warning); //$NON-NLS-1$
- }
- context.addWarning(toAdd);
- }
+ if (warning != null) {
+ context.addWarning(warning);
+ if (LogManager.isMessageToBeRecorded(LogConstants.CTX_CONNECTOR, MessageLevel.DETAIL))
{
+ while (warning != null) {
+ LogManager.logDetail(LogConstants.CTX_CONNECTOR, context.getRequestId() + "
Warning: ", warning); //$NON-NLS-1$
+ warning = warning.getNextWarning();
+ }
+ }
+ }
this.statement.clearWarnings();
}
}