diff --git a/db/src/org/netbeans/modules/db/explorer/DatabaseConnection.java b/db/src/org/netbeans/modules/db/explorer/DatabaseConnection.java --- a/db/src/org/netbeans/modules/db/explorer/DatabaseConnection.java +++ b/db/src/org/netbeans/modules/db/explorer/DatabaseConnection.java @@ -56,6 +56,13 @@ import java.sql.SQLWarning; import java.text.MessageFormat; import java.util.*; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; import org.netbeans.api.db.explorer.DatabaseException; @@ -288,7 +295,7 @@ if (LOGGER.isLoggable(Level.FINE) && warnings != null) { LOGGER.log(Level.FINE, "Warnings while trying vitality of connection: " + warnings); } - return ! conn.isClosed(); + return ! checkClosedWithTimeout(conn); } catch (Exception ex) { if (dbconn != null) { try { @@ -302,6 +309,33 @@ } } + private static boolean checkClosedWithTimeout(final Connection connection) { + ExecutorService executor = Executors.newCachedThreadPool(); + Callable task = new Callable() { + @Override + public Boolean call() { + try { + return connection.isClosed(); + } catch (SQLException ex) { + LOGGER.log(Level.FINE, + "While trying vitality of connection: " //NOI18N + + ex.getLocalizedMessage(), ex); + return false; + } + } + }; + Future future = executor.submit(task); + try { + return future.get(1, TimeUnit.SECONDS); + } catch (TimeoutException e) { + return false; + } catch (InterruptedException e) { + return false; + } catch (ExecutionException e) { + throw new RuntimeException(e); + } + } + public static boolean test(Connection conn, String connectionName) { try { if (! isVitalConnection(conn, null)) {