From: Date: January 10 2007 10:59pm Subject: Connector/J commit: r6289 - branches/branch_5_0/connector-j branches/branch_5_0/connector-j/src/com/mysql/jdbc trunk/connector-j trunk/connector-j/src/com/mysql/jdbc List-Archive: http://lists.mysql.com/commits/17893 X-Bug: 21480 Message-Id: <200701102159.l0ALxTZH015280@bk-internal.mysql.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modified: branches/branch_5_0/connector-j/CHANGES branches/branch_5_0/connector-j/src/com/mysql/jdbc/StandardSocketFactory.java trunk/connector-j/CHANGES trunk/connector-j/src/com/mysql/jdbc/StandardSocketFactory.java Log: Fixed BUG#21480 - Some exceptions thrown out of StandardSocketFactory were needlessly wrapped, obscurring their true cause, especially when using socket timeouts. (Note, I'm at a loss as to how to test this reliably, which is why there isn't a testcase for it). Modified: branches/branch_5_0/connector-j/CHANGES =================================================================== --- branches/branch_5_0/connector-j/CHANGES 2007-01-10 21:29:26 UTC (rev 6288) +++ branches/branch_5_0/connector-j/CHANGES 2007-01-10 21:59:27 UTC (rev 6289) @@ -61,7 +61,11 @@ case-insensitive on the first character of the target. This bug broke rewriteBatchedStatements functionality when prepared statements don't use upper-case for the VALUES clause in their statements. - + + - Fixed BUG#21480 - Some exceptions thrown out of StandardSocketFactory + were needlessly wrapped, obscurring their true cause, especially when + using socket timeouts. + 10-20-06 - Version 5.0.4 - Fixed BUG#21379 - column names don't match metadata in cases Modified: branches/branch_5_0/connector-j/src/com/mysql/jdbc/StandardSocketFactory.java =================================================================== --- branches/branch_5_0/connector-j/src/com/mysql/jdbc/StandardSocketFactory.java 2007-01-10 21:29:26 UTC (rev 6288) +++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/StandardSocketFactory.java 2007-01-10 21:59:27 UTC (rev 6289) @@ -137,7 +137,7 @@ InetAddress[] possibleAddresses = InetAddress .getAllByName(this.host); - Exception caughtWhileConnecting = null; + Throwable caughtWhileConnecting = null; // Need to loop through all possible addresses, in case // someone has IPV6 configured (SuSE, for example...) @@ -153,8 +153,7 @@ } if (rawSocket == null) { - throw new SocketException(caughtWhileConnecting - .toString()); + unwrapExceptionToProperClassAndThrowIt(caughtWhileConnecting); } } else { // must explicitly state this due to classloader issues @@ -169,7 +168,7 @@ InetAddress[] possibleAddresses = InetAddress .getAllByName(this.host); - Exception caughtWhileConnecting = null; + Throwable caughtWhileConnecting = null; // Need to loop through all possible addresses, in case // someone has IPV6 configured (SuSE, for example...) @@ -195,16 +194,11 @@ } if (rawSocket == null) { - throw new SocketException(caughtWhileConnecting - .toString()); + unwrapExceptionToProperClassAndThrowIt(caughtWhileConnecting); } } catch (Throwable t) { - if (!(t instanceof SocketException)) { - throw new SocketException(t.toString()); - } - - throw (SocketException) t; + unwrapExceptionToProperClassAndThrowIt(t); } } @@ -221,4 +215,24 @@ throw new SocketException("Unable to create socket"); } + + private void unwrapExceptionToProperClassAndThrowIt(Throwable caughtWhileConnecting) throws SocketException, IOException { + if (caughtWhileConnecting instanceof InvocationTargetException) { + + // Replace it with the target, don't use 1.4 chaining as this still + // needs to run on older VMs + caughtWhileConnecting = ((InvocationTargetException)caughtWhileConnecting).getTargetException(); + } + + if (caughtWhileConnecting instanceof SocketException) { + throw (SocketException)caughtWhileConnecting; + } + + if (caughtWhileConnecting instanceof IOException) { + throw (IOException)caughtWhileConnecting; + } + + throw new SocketException(caughtWhileConnecting + .toString()); + } } Modified: trunk/connector-j/CHANGES =================================================================== --- trunk/connector-j/CHANGES 2007-01-10 21:29:26 UTC (rev 6288) +++ trunk/connector-j/CHANGES 2007-01-10 21:59:27 UTC (rev 6289) @@ -57,7 +57,11 @@ case-insensitive on the first character of the target. This bug broke rewriteBatchedStatements functionality when prepared statements don't use upper-case for the VALUES clause in their statements. - + + - Fixed BUG#21480 - Some exceptions thrown out of StandardSocketFactory + were needlessly wrapped, obscurring their true cause, especially when + using socket timeouts. + 10-20-06 - Version 5.0.4 - Fixed BUG#21379 - column names don't match metadata in cases Modified: trunk/connector-j/src/com/mysql/jdbc/StandardSocketFactory.java =================================================================== --- trunk/connector-j/src/com/mysql/jdbc/StandardSocketFactory.java 2007-01-10 21:29:26 UTC (rev 6288) +++ trunk/connector-j/src/com/mysql/jdbc/StandardSocketFactory.java 2007-01-10 21:59:27 UTC (rev 6289) @@ -27,6 +27,7 @@ import java.io.IOException; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.InetAddress; @@ -136,7 +137,7 @@ InetAddress[] possibleAddresses = InetAddress .getAllByName(this.host); - Exception caughtWhileConnecting = null; + Throwable caughtWhileConnecting = null; // Need to loop through all possible addresses, in case // someone has IPV6 configured (SuSE, for example...) @@ -152,8 +153,7 @@ } if (rawSocket == null) { - throw new SocketException(caughtWhileConnecting - .toString()); + unwrapExceptionToProperClassAndThrowIt(caughtWhileConnecting); } } else { // must explicitly state this due to classloader issues @@ -162,24 +162,25 @@ Class inetSocketAddressClass = Class .forName("java.net.InetSocketAddress"); Constructor addrConstructor = inetSocketAddressClass - .getConstructor(new Class[] { InetAddress.class, - Integer.TYPE }); + .getConstructor(new Class[] { + InetAddress.class, Integer.TYPE }); - InetAddress[] possibleAddresses = InetAddress - .getAllByName(this.host); + InetAddress[] possibleAddresses = InetAddress + .getAllByName(this.host); - Exception caughtWhileConnecting = null; + Throwable caughtWhileConnecting = null; - // Need to loop through all possible addresses, in case - // someone has IPV6 configured (SuSE, for example...) + // Need to loop through all possible addresses, in case + // someone has IPV6 configured (SuSE, for example...) - for (int i = 0; i < possibleAddresses.length; i++) { - - try { - Object sockAddr = addrConstructor - .newInstance(new Object[] { possibleAddresses[i], - new Integer(port) }); - + for (int i = 0; i < possibleAddresses.length; i++) { + + try { + Object sockAddr = addrConstructor + .newInstance(new Object[] { + possibleAddresses[i], + new Integer(port) }); + rawSocket = new Socket(); connectWithTimeoutMethod.invoke(rawSocket, new Object[] { sockAddr, @@ -194,16 +195,11 @@ } if (rawSocket == null) { - throw new SocketException(caughtWhileConnecting - .toString()); + unwrapExceptionToProperClassAndThrowIt(caughtWhileConnecting); } } catch (Throwable t) { - if (!(t instanceof SocketException)) { - throw new SocketException(t.toString()); - } - - throw (SocketException) t; + unwrapExceptionToProperClassAndThrowIt(t); } } @@ -220,4 +216,26 @@ throw new SocketException("Unable to create socket"); } + + private void unwrapExceptionToProperClassAndThrowIt( + Throwable caughtWhileConnecting) throws SocketException, + IOException { + if (caughtWhileConnecting instanceof InvocationTargetException) { + + // Replace it with the target, don't use 1.4 chaining as this still + // needs to run on older VMs + caughtWhileConnecting = ((InvocationTargetException) caughtWhileConnecting) + .getTargetException(); + } + + if (caughtWhileConnecting instanceof SocketException) { + throw (SocketException) caughtWhileConnecting; + } + + if (caughtWhileConnecting instanceof IOException) { + throw (IOException) caughtWhileConnecting; + } + + throw new SocketException(caughtWhileConnecting.toString()); + } }