Index: src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java (revision 1236838) +++ src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWatcher.java (working copy) @@ -225,6 +225,14 @@ public void registerListener(ZooKeeperListener listener) { listeners.add(listener); } + + /** + * Unregister the specified listener. + * @param listener + */ + public void unregisterListener(ZooKeeperListener listener) { + listeners.remove(listener); + } /** * Register the specified listener to receive ZooKeeper events and add it as Index: src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperNodeTracker.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperNodeTracker.java (revision 1236838) +++ src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperNodeTracker.java (working copy) @@ -89,6 +89,7 @@ } public synchronized void stop() { + this.watcher.unregisterListener(this); this.stopped = true; notifyAll(); } Index: src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java (revision 1236838) +++ src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java (working copy) @@ -596,15 +596,32 @@ private synchronized void resetZooKeeperTrackers() throws ZooKeeperConnectionException { LOG.info("Trying to reconnect to zookeeper"); - masterAddressTracker.stop(); - masterAddressTracker = null; - rootRegionTracker.stop(); - rootRegionTracker = null; + if (masterAddressTracker != null) { + masterAddressTracker.stop(); + masterAddressTracker = null; + } + if (rootRegionTracker != null) { + rootRegionTracker.stop(); + rootRegionTracker = null; + } + if (this.zooKeeper != null) { + this.zooKeeper.close(); + this.zooKeeper = null; + } clusterId = null; - this.zooKeeper = null; setupZookeeperTrackers(); } + /** + * {@inheritDoc} + */ + @Override + public void resetConnection() throws ZooKeeperConnectionException { + resetZooKeeperTrackers(); + this.aborted = false; + this.closed = false; + } + public Configuration getConfiguration() { return this.conf; } @@ -802,7 +819,9 @@ private HRegionLocation locateRegion(final byte [] tableName, final byte [] row, boolean useCache) throws IOException { - if (this.closed) throw new IOException(toString() + " closed"); + if (this.closed) { + throw new ClosedConnectionException(toString() + " closed"); + } if (tableName == null || tableName.length == 0) { throw new IllegalArgumentException( "table name cannot be null or zero length"); @@ -1331,11 +1350,17 @@ public T getRegionServerWithRetries(ServerCallable callable) throws IOException, RuntimeException { + if (this.closed) { + throw new ClosedConnectionException(toString() + " closed"); + } return callable.withRetries(); } public T getRegionServerWithoutRetries(ServerCallable callable) throws IOException, RuntimeException { + if (this.closed) { + throw new ClosedConnectionException(toString() + " closed"); + } return callable.withoutRetries(); } Index: src/main/java/org/apache/hadoop/hbase/client/HConnection.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/client/HConnection.java (revision 1236838) +++ src/main/java/org/apache/hadoop/hbase/client/HConnection.java (working copy) @@ -64,6 +64,14 @@ public Configuration getConfiguration(); /** + * Resets this connection. + * This might become necessary if the connection to the zookeeper + * ensemble was lost. + * @throws ZooKeeperConnectionException + */ + public void resetConnection() throws ZooKeeperConnectionException; + + /** * Retrieve ZooKeeperWatcher used by this connection. * @return ZooKeeperWatcher handle being used by the connection. * @throws IOException if a remote or network exception occurs Index: src/main/java/org/apache/hadoop/hbase/client/ClosedConnectionException.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/client/ClosedConnectionException.java (revision 0) +++ src/main/java/org/apache/hadoop/hbase/client/ClosedConnectionException.java (revision 0) @@ -0,0 +1,36 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.hbase.client; + +import java.io.IOException; + +/** + * Thrown when HConnection has been closed. + */ +public class ClosedConnectionException extends IOException { + private static final long serialVersionUID = 8792360655678089586L; + + public ClosedConnectionException() { + super(); + } + + public ClosedConnectionException(String s) { + super(s); + } +}