[jboss-cvs] JBossAS SVN: r92790 - trunk/connector/src/main/org/jboss/resource/adapter/jdbc/vendor.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Aug 25 09:08:45 EDT 2009


Author: jesper.pedersen
Date: 2009-08-25 09:08:45 -0400 (Tue, 25 Aug 2009)
New Revision: 92790

Modified:
   trunk/connector/src/main/org/jboss/resource/adapter/jdbc/vendor/MSSQLValidConnectionChecker.java
Log:
[JBAS-7149] ValidConnectionChecker implementation for MS SQL Server JDBC driver version 2.0

Modified: trunk/connector/src/main/org/jboss/resource/adapter/jdbc/vendor/MSSQLValidConnectionChecker.java
===================================================================
--- trunk/connector/src/main/org/jboss/resource/adapter/jdbc/vendor/MSSQLValidConnectionChecker.java	2009-08-25 13:00:41 UTC (rev 92789)
+++ trunk/connector/src/main/org/jboss/resource/adapter/jdbc/vendor/MSSQLValidConnectionChecker.java	2009-08-25 13:08:45 UTC (rev 92790)
@@ -21,63 +21,172 @@
  */
 package org.jboss.resource.adapter.jdbc.vendor;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.sql.ResultSet;
 
 import org.jboss.logging.Logger;
 import org.jboss.resource.adapter.jdbc.ValidConnectionChecker;
 
 /**
- * A MSSQLValidConnectionChecker.
- * 
- * @author <a href="weston.price at jboss.com">Weston Price</a>
- * @version $Revision$
+ * Implements sql connection validation check.
+ * This should work on just about any version of the database,
+ * but will use isValid() method with MSSQL JDBC driver 2.0 or later.
+ * Prior to that version it just executes "SELECT 1" query.
+ *
+ * <p>Please note that the isValid() method requires java 6.
+ *
+ * <p>The code was inspired by MySQLValidConnectionChecker. See it's javadoc for
+ * authors info. This code is released under the LGPL license.
+ *
+ * @author <a href="weston.price at jboss.com">Weston Price</a>              
+ * @author Dmitry L (dmitryl att artezio dott com)
  */
 public class MSSQLValidConnectionChecker implements ValidConnectionChecker, Serializable
 {
-   private static final String QUERY = "SELECT 1";
-   private static final Logger log = Logger.getLogger(MSSQLValidConnectionChecker.class);
+   private static transient Logger log;
+
+   private static final String SQLSERVER_CONNECTION_CLASS = "com.microsoft.sqlserver.jdbc.SQLServerConnection";
+
+   private static final String VALIDATION_SQL_QUERY = "SELECT 1";
    
-   /** The serialVersionUID */
-   private static final long serialVersionUID = 3995516551833725723L;
+   private transient boolean driverHasIsValidMethod;
 
-   public SQLException isValidConnection(final Connection c)
+   // The validation method
+   private transient Method isValid;
+
+   // The timeout for isValid method
+   private static Object[] timeoutParam = new Object[]{1};
+
+   private static final long serialVersionUID = 4609709370615627138L;
+
+   public MSSQLValidConnectionChecker()
    {
-      SQLException sqe = null;
-      Statement stmt = null;
+      initIsValid();
+   }
 
-      try
+   public SQLException isValidConnection(Connection c)
+   {
+      // if there is a isValid method then use it
+      if (driverHasIsValidMethod)
       {
-         stmt = c.createStatement();
-         stmt.execute(QUERY);
+         try
+         {
+            Boolean valid = (Boolean) isValid.invoke(c, timeoutParam);
+            if (!valid)
+               return new SQLException("Connection is unvalid or " + timeoutParam[0] + " sec timeout has expired");
+         }
+         catch (Exception e)
+         {
+            if (e instanceof SQLException)
+            {
+               return (SQLException) e;
+            }
+            else
+            {
+               log.warn("Unexpected error in isValid() method", e);
+               return new SQLException("isValid() method failed: " + e.toString());
+            }
+         }
       }
-     
-      catch (SQLException e)
+      else
       {
-         log.warn("warning: connection validation failed for current managed connection.");
-         sqe = e;
-      }
-      finally
-      {
+         // otherwise just use a sql statement
+         Statement stmt = null;
+         ResultSet rs = null;
          try
          {
-            if(stmt != null)
+            stmt = c.createStatement();
+            rs = stmt.executeQuery(VALIDATION_SQL_QUERY);
+         }
+         catch (Exception e)
+         {
+            if (e instanceof SQLException)
             {
-               stmt.close();
-               
+               return (SQLException) e;
+            } 
+            else
+            {
+               log.warn("Unexpected error in '" + VALIDATION_SQL_QUERY + "'", e);
+               return new SQLException("'" + VALIDATION_SQL_QUERY + "' failed: " + e.toString());
             }
          }
-         catch (SQLException e)
+         finally
          {
-            log.warn("simple close failed for managed connection", e);
-            
+            //cleanup the Statement
+            try
+            {
+               if (rs != null)
+                  rs.close();
+            }
+            catch (SQLException ignore)
+            {
+               // ignore
+            }
+
+            try
+            {
+               if (stmt != null)
+                  stmt.close();
+            }
+            catch (SQLException ignore)
+            {
+               // ignore
+            }
          }
+      }
+      return null;
+   }
 
+   private void initIsValid()
+   {
+      log = Logger.getLogger(this.getClass());
+      driverHasIsValidMethod = false;
+
+      Class connectionClazz;
+      try
+      {
+         connectionClazz = Thread.currentThread().getContextClassLoader().loadClass(SQLSERVER_CONNECTION_CLASS);
+         isValid = connectionClazz.getMethod("isValid", new Class[]{int.class});
+         if (isValid != null && !(Modifier.isAbstract(isValid.getModifiers())))
+         {
+            driverHasIsValidMethod = true;
+         }
       }
-            
-      return sqe;
+      catch (ClassNotFoundException e)
+      {
+         log.error("Cannot resolve " + SQLSERVER_CONNECTION_CLASS +
+                   " class. Wrong ValidConnectionChecker is configured?" +
+                   " Will use '" + VALIDATION_SQL_QUERY + "' instead.", e);
+      } 
+      catch (SecurityException e)
+      {
+         log.error("Cannot access " + SQLSERVER_CONNECTION_CLASS + ".isValid() " +
+                   "Will use '" + VALIDATION_SQL_QUERY + "' instead.", e);
+      }
+      catch (NoSuchMethodException e)
+      {
+         if (log.isDebugEnabled()) {
+            log.debug("Cannot resolve isValid() method for " + SQLSERVER_CONNECTION_CLASS +
+                      " class (JDBC driver 2.0+). Will use '" + VALIDATION_SQL_QUERY +
+                      "' instead (JDBC driver 1.2 and earlier).");
+         }
+      }
    }
 
+   private void writeObject(ObjectOutputStream out) throws IOException
+   {
+   }
+
+   private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
+   {
+      initIsValid();
+   }
 }




More information about the jboss-cvs-commits mailing list