一个无法捕获的hbase表不存在异常

有一段代码如下,是想捕获hbase表不存在的异常:

   try {
        Configuration conf = HBaseConfiguration.create();
        this.h_table = new HTable(conf, tableName);
    } catch (Exception e) {
        logger.error("create htable error");
    }

运行的时候发现这个异常并没有捕获掉,而是在程序的其他地方发现表不存在时报了异常:

2012-10-25 10:59:35,236 WARN org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation: Encountered problems when prefetch META table: 
org.apache.hadoop.hbase.client.RetriesExhaustedException: Failed after attempts=10, exceptions:
Thu Oct 25 10:58:55 CST 2012, org.apache.hadoop.hbase.client.HTable$4@40389922, java.io.IOException: java.io.IOException: java.lang.NullPointerException
	at org.apache.hadoop.hbase.regionserver.HRegionServer
.convertThrowableToIOE(HRegionServer.java:1100)
	at org.apache.hadoop.hbase.regionserver.HRegionServer
.convertThrowableToIOE(HRegionServer.java:1089)
	at org.apache.hadoop.hbase.regionserver.HRegionServer
.getClosestRowBefore(HRegionServer.java:1814)
	at sun.reflect.GeneratedMethodAccessor13.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl
.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.hadoop.hbase.ipc.WritableRpcEngine$Server
.call(WritableRpcEngine.java:364)
	at org.apache.hadoop.hbase.ipc.HBaseServer$Handler.run(HBaseServer.java:1326)
Caused by: java.lang.NullPointerException
	at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation
.getRegionServerWithRetries(HConnectionManager.java:1345)
	at org.apache.hadoop.hbase.client.HTable.getRowOrBefore(HTable.java:655)
	at org.apache.hadoop.hbase.client.MetaScanner.metaScan(MetaScanner.java:155)
	at org.apache.hadoop.hbase.client.MetaScanner.access$000(MetaScanner.java:52)
	at org.apache.hadoop.hbase.client.MetaScanner$1.connect(MetaScanner.java:130)
	at org.apache.hadoop.hbase.client.MetaScanner$1.connect(MetaScanner.java:127)
	at org.apache.hadoop.hbase.client.HConnectionManager
.execute(HConnectionManager.java:360)
	at org.apache.hadoop.hbase.client.MetaScanner.metaScan(MetaScanner.java:127)
	at org.apache.hadoop.hbase.client.MetaScanner.metaScan(MetaScanner.java:103)
	at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation
.prefetchRegionCache(HConnectionManager.java:876)
	at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation
.locateRegionInMeta(HConnectionManager.java:930)
	at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation
.locateRegion(HConnectionManager.java:818)
	at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation
.locateRegion(HConnectionManager.java:782)
	at org.apache.hadoop.hbase.client.HTable.finishSetup(HTable.java:249)
	at org.apache.hadoop.hbase.client.HTable.<init>(HTable.java:213)
	at org.apache.hadoop.hbase.client.HTable.<init>(HTable.java:171)
	at com.company.queue.HBaseTableQueue.<init>(HBaseTableQueue.java:25)

为什么当hbase中的表不存在,通过try catch 的方式是无法捕获这个异常的,因为hbase代码内部捕获了这个异常。

在 org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation 第879行:

 try {
        // pre-fetch certain number of regions info at region cache.
        MetaScanner.metaScan(conf, visitor, tableName, row,
            this.prefetchRegionLimit);
      } catch (IOException e) {
        LOG.warn("Encountered problems when prefetch META table: ", e);
      }

解决方法是在创建表之前先用HBaseAdmin来判断表是否存在:

public void tableExists(String tablename) throws IOException{
    Configuration conf = HBaseConfiguration.create();
    HBaseAdmin admin = new HBaseAdmin(conf);
    if(!admin.tableExists(tablename)){
       System.out.println("Table " + tablename + " not exists!");
  }
}

HBaseAdmin是对hbase表元信息的管理接口,还可以创建表,删除表以及修改表的属性等。详见Hbase 官方文档

发表评论

电子邮件地址不会被公开。 必填项已用*标注