Index: hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestFSHDFSUtils.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestFSHDFSUtils.java (revision 1500986) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestFSHDFSUtils.java (working copy) @@ -20,6 +20,7 @@ import static org.junit.Assert.assertTrue; import java.io.IOException; +import java.util.regex.Pattern; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; @@ -73,6 +74,29 @@ } /** + * Test that isFileClosed exists in certain hadoop releases. + * @throws IOException + */ + @Test + public void testExistenceOfIsFileClosed() throws IOException { + String hadoopVer = VersionInfo.getVersion(); + // known versions where DistributedFileSystem supports IsFileClosed(Path) + final Pattern knownVers[] = { + Pattern.compile("1\\.2\\."), + Pattern.compile("2\\.1\\.") + }; + for (Pattern pat : knownVers) { + if (pat.matcher(hadoopVer).matches()) { + try { + DistributedFileSystem.class.getMethod("isFileClosed", new Class[]{ Path.class }); + break; + } catch (NoSuchMethodException nsme) { + throw new IOException(nsme); + } + } + } + } + /** * Test that isFileClosed makes us recover lease faster. * @throws IOException */ @@ -88,10 +112,10 @@ // therefore return true if we are to break the loop. Mockito.when(dfs.recoverLease(FILE)). thenReturn(false).thenReturn(false).thenReturn(true); - Mockito.when(dfs.isFileClosed(FILE.toString())).thenReturn(true); + Mockito.when(dfs.isFileClosed(FILE)).thenReturn(true); assertTrue(this.fsHDFSUtils.recoverDFSFileLease(dfs, FILE, HTU.getConfiguration(), reporter)); - Mockito.verify(dfs, Mockito.times(3)).recoverLease(FILE); - Mockito.verify(dfs, Mockito.times(1)).isFileClosed(FILE.toString()); + Mockito.verify(dfs, Mockito.times(2)).recoverLease(FILE); + Mockito.verify(dfs, Mockito.times(1)).isFileClosed(FILE); } /** @@ -102,7 +126,7 @@ * Close status of a file. Copied over from HDFS-4525 * @return true if file is already closed **/ - public boolean isFileClosed(String f) throws IOException{ + public boolean isFileClosed(Path f) throws IOException{ return false; } } Index: hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSHDFSUtils.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSHDFSUtils.java (revision 1500986) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSHDFSUtils.java (working copy) @@ -95,9 +95,16 @@ // is dead. We set it to 61 seconds, 1 second than the default READ_TIMEOUT in HDFS, the // default value for DFS_CLIENT_SOCKET_TIMEOUT_KEY. long subsequentPause = conf.getInt("hbase.lease.recovery.dfs.timeout", 61 * 1000); + + Method isFileClosedMeth = null; + try { + isFileClosedMeth = dfs.getClass().getMethod("isFileClosed", new Class[]{ Path.class }); + } catch (NoSuchMethodException nsme) { + LOG.debug("isFileClosed not available"); + } boolean recovered = false; // We break the loop if we succeed the lease recovery, timeout, or we throw an exception. - for (int nbAttempt = 0; true; nbAttempt++) { + for (int nbAttempt = 0; !recovered; nbAttempt++) { recovered = recoverLease(dfs, nbAttempt, p, startWaiting); if (recovered) break; checkIfCancelled(reporter); @@ -113,7 +120,10 @@ while ((EnvironmentEdgeManager.currentTimeMillis() - localStartWaiting) < subsequentPause) { Thread.sleep(conf.getInt("hbase.lease.recovery.pause", 1000)); - if (isFileClosed(dfs, p)) break; + if (isFileClosedMeth != null && isFileClosed(dfs, isFileClosedMeth, p)) { + recovered = true; + break; + } checkIfCancelled(reporter); } } @@ -181,21 +191,17 @@ /** * Call HDFS-4525 isFileClosed if it is available. * @param dfs + * @param m * @param p * @return True if file is closed. */ - boolean isFileClosed(final DistributedFileSystem dfs, final Path p) { + private boolean isFileClosed(final DistributedFileSystem dfs, final Method m, final Path p) { try { - Method m = dfs.getClass().getMethod("isFileClosed", new Class[] {String.class}); - return (Boolean) m.invoke(dfs, p.toString()); + return (Boolean) m.invoke(dfs, p); } catch (SecurityException e) { LOG.warn("No access", e); - } catch (NoSuchMethodException e) { - if (LOG.isTraceEnabled()) { - LOG.trace("noSuchMethod isFileClosed (HDFS-4525); making do without"); - } } catch (Exception e) { - LOG.warn("Failed invocation", e); + LOG.warn("Failed invocation for " + p.toString(), e); } return false; }