### Question:
TabletLocatorImpl extends TabletLocator { @Override public TabletLocation locateTablet(ClientContext context, Text row, boolean skipRow, boolean retry) throws AccumuloException, AccumuloSecurityException, TableNotFoundException { OpTimer timer = null; if (log.isTraceEnabled()) { log.trace("tid={} Locating tablet table={} row={} skipRow={} retry={}", Thread.currentThread().getId(), tableId, TextUtil.truncate(row), skipRow, retry); timer = new OpTimer().start(); } while (true) { LockCheckerSession lcSession = new LockCheckerSession(); TabletLocation tl = _locateTablet(context, row, skipRow, retry, true, lcSession); if (retry && tl == null) { sleepUninterruptibly(100, TimeUnit.MILLISECONDS); if (log.isTraceEnabled()) log.trace("Failed to locate tablet containing row {} in table {}, will retry...", TextUtil.truncate(row), tableId); continue; } if (timer != null) { timer.stop(); log.trace("tid={} Located tablet {} at {} in {}", Thread.currentThread().getId(), (tl == null ? "null" : tl.tablet_extent), (tl == null ? "null" : tl.tablet_location), String.format("%.3f secs", timer.scale(TimeUnit.SECONDS))); } return tl; } } TabletLocatorImpl(TableId tableId, TabletLocator parent, TabletLocationObtainer tlo,
      TabletServerLockChecker tslc); @Override void binMutations(ClientContext context, List<T> mutations,
      Map<String,TabletServerMutations<T>> binnedMutations, List<T> failures); @Override List<Range> binRanges(ClientContext context, List<Range> ranges,
      Map<String,Map<KeyExtent,List<Range>>> binnedRanges); @Override void invalidateCache(KeyExtent failedExtent); @Override void invalidateCache(Collection<KeyExtent> keySet); @Override void invalidateCache(ClientContext context, String server); @Override void invalidateCache(); @Override TabletLocation locateTablet(ClientContext context, Text row, boolean skipRow,
      boolean retry);  }### Answer:
@Test public void testBug2() throws Exception { KeyExtent mte1 = new KeyExtent(MetadataTable.ID, new Text("~"), RTE.endRow()); KeyExtent mte2 = new KeyExtent(MetadataTable.ID, null, new Text("~")); TServers tservers = new TServers(); TestTabletLocationObtainer ttlo = new TestTabletLocationObtainer(tservers); RootTabletLocator rtl = new TestRootTabletLocator(); TabletLocatorImpl rootTabletCache = new TabletLocatorImpl(MetadataTable.ID, rtl, ttlo, new YesLockChecker()); TabletLocatorImpl tab0TabletCache = new TabletLocatorImpl(TableId.of("0"), rootTabletCache, ttlo, new YesLockChecker()); setLocation(tservers, "tserver1", RTE, mte1, "tserver2"); setLocation(tservers, "tserver1", RTE, mte2, "tserver3"); Map<KeyExtent,SortedMap<Key,Value>> ts3 = new HashMap<>(); ts3.put(mte2, new TreeMap<>()); tservers.tservers.put("tserver3", ts3); assertNull(tab0TabletCache.locateTablet(context, new Text("row_0000000000"), false, false)); }
@Test public void testAccumulo1248() { TServers tservers = new TServers(); TabletLocatorImpl metaCache = createLocators(tservers, "tserver1", "tserver2", "foo"); KeyExtent ke1 = nke("foo", null, null); setLocation(tservers, "tserver2", MTE, ke1, "L1", "I1"); setLocation(tservers, "tserver2", MTE, ke1, "L2", "I2"); try { metaCache.locateTablet(context, new Text("a"), false, false); fail(); } catch (Exception e) { } }