java - 无法从 Tomcat 连接到 HBase

标签 java tomcat servlets hbase

我有一个 servlet 项目,我将 hbase-x.x.x.jarhadoop-x.x.x.jar 放入 WebContent/Web-INF/lib目录和这些 API 在编译时可用。

HBase 上的写入应该在处理 POST 请求时发生。

这是我的 servlet 代码:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    handlePostRequest(request, response);
}

public void handlePostRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
    request.setCharacterEncoding(StandardCharsets.UTF_8.name());
    response.setCharacterEncoding(StandardCharsets.UTF_8.name());
    response.setContentType("application/json");
    PrintWriter out = response.getWriter();
    String activityLogTxt = request.getParameter("activityLog");
    out.print(activityLogTxt);

    List<TableEntry> entries = new ArrayList<TableEntry>();
    entries.add(new TableEntry(TABLE_COLUMN_FAMILY, COLUMN_ACTIVITY_LOG, activityLogTxt));
    DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");

    // Everything is okay till this  
    HBaseManager.getHBaseManager().writeToTable(dateFormat.format(new Date()), entries);
  }

这是我的 HBaseManager.java

public class HBaseManager {

//    private static Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

    private final static String ZK_QUORUM = "localhost";
    private final static int ZK_CLIENT_PORT = 2181;

    private static Configuration hBaseConfig = null;
    private static HBaseAdmin hBaseAdmin = null;

    private static class HBaseManagerSingleton {
        private final static HBaseManager HBASE_MANAGER_INSTANCE = new HBaseManager(); 
    }

    public static HBaseManager getHBaseManager() {
        return HBaseManagerSingleton.HBASE_MANAGER_INSTANCE;
    }

    private HBaseManager() {
        if(HBaseManager.HBaseManagerSingleton.HBASE_MANAGER_INSTANCE != null) {
            throw new InstantiationError("Creating of this object is not allowed. The singleton object is accessible by HBaseManager.getHBaseManager()");
        }
    }

    public Configuration getConfiguration() {
        if(hBaseConfig == null) {
            hBaseConfig = HBaseConfiguration.create();
            hBaseConfig.set(HConstants.ZOOKEEPER_QUORUM, ZK_QUORUM);
            hBaseConfig.setInt(HConstants.ZOOKEEPER_CLIENT_PORT, ZK_CLIENT_PORT);
        }
        return hBaseConfig;
    }


    /**
     * Return connection instance from Connection pool
     * Handy for high-end multi-threaded access
     * @return HConnection instance
     */
    public HConnection createHConnection() {
        try {
            HConnection hConnection = HConnectionManager.createConnection(getConfiguration());
            return hConnection;
        } catch (ZooKeeperConnectionException ex) {
//            logger.error(ex.toString());
        }
        return null;
    }

    public HBaseAdmin getAdmin() {
        if(hBaseAdmin == null) {
            try {
                hBaseAdmin = new HBaseAdmin(getConfiguration());
                return hBaseAdmin;
            } catch (MasterNotRunningException ex) {
//                logger.error(ex.toString());
            } catch (ZooKeeperConnectionException ex) {
//                logger.error(ex.toString());
            }
        }
        return hBaseAdmin;
    }

    /**
     * Create HTable instance. HTable is not thread-safe, not suitable for multi-threaded scenario
     * Must invoke close() after operation
     * @param tableName
     * @return HTable instance
     * @throws IOException
     */
    public HTable createHTable(String tableName) throws IOException {
        HBaseAdmin hBaseAdmin = getHBaseManager().getAdmin();
        if (!hBaseAdmin.tableExists(tableName)) {
            String msg = "Table '" + tableName + "' doesn't exist in hbase";
//            logger.error(msg);
            throw new IOException(msg);
        }
        if (hBaseAdmin.isTableDisabled(tableName)) {
            String msg = "Table '" + tableName + "' is disabled";
//            logger.error(msg);
            throw new IOException(msg);
        }
        return new HTable(getHBaseManager().getConfiguration(), tableName);
    }


    public static class TableEntry {
      private String columnFamily;
      private String qualifier;
      private String value;

      public TableEntry(String columnFamily, String qualifier, String value) {
        this.columnFamily = columnFamily;
        this.qualifier = qualifier;
        this.value = value;
      }

      public String getColumnFamily() {
        return columnFamily;
      }

      public String getQualifier() {
        return qualifier;
      }

      public String getValue() {
        return value;
      }

    };

    public void writeToTable(String rowKey, List<TableEntry> entries) {
      try {
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        Date date = new Date();
        String tableName = dateFormat.format(date) + "_tmp";
        HTable activityLogTable = createHTable(tableName);
        Put put = new Put(Bytes.toBytes(rowKey));
        for(TableEntry entry : entries) {
          put.add(Bytes.toBytes(entry.getColumnFamily()), Bytes.toBytes(entry.getQualifier()), Bytes.toBytes(entry.getValue()));
        }
        activityLogTable.put(put);

        activityLogTable.close();

      } catch (IOException ex) {
//        logger.error(ex.getMessage());
      }
    }

    public void close() throws IOException {
        if(hBaseAdmin != null) {
            hBaseAdmin.close();
        }
    }
}

但是当写入即将发生/HBase API 将被调用时,这种情况正在发生并且写入不成功:

SEVERE: Servlet.service() for servlet [com.ringid.adserver.AdEngineServlet] in context with path [/AdServer] threw exception [Servlet execution threw an exception] with root cause
java.lang.NoClassDefFoundError: Could not initialize class org.apache.hadoop.hbase.HBaseConfiguration
    at com.ringid.adserver.activityLogStorage.HBaseManager.getConfiguration(HBaseManager.java:60)
    at com.ringid.adserver.activityLogStorage.HBaseManager.getAdmin(HBaseManager.java:86)
    at com.ringid.adserver.activityLogStorage.HBaseManager.createHTable(HBaseManager.java:105)
    at com.ringid.adserver.activityLogStorage.HBaseManager.writeToTable(HBaseManager.java:167)
    at com.ringid.adserver.AdEngineServlet.handlePostRequest(AdEngineServlet.java:200)
    at com.ringid.adserver.AdEngineServlet.doPost(AdEngineServlet.java:88)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:94)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:502)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1132)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1533)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1489)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

我在 Web-INF\lib 目录中的其他库正在运行,但对于 HBase,它显示 NoClassDefFoundError。你能给我一些建议吗?

编辑

我检查并确保该类存在于 jar 中。

> jar tvf hbase-0.94.27.jar | grep HBaseConfiguration
4911 Thu Mar 19 06:18:06 BDT 2015 org/apache/hadoop/hbase/HBaseConfiguration.class

最佳答案

继续评论线程,因为 SO 提示评论太多。

如果您从 eclipse 运行,您确定这些 jar 正在导出吗?尝试转到项目属性 -> Java 构建路径并将 2 个 jar 添加为库,并将它们标记为导出。

您似乎遇到了范围界定问题:

private static class HBaseManagerSingleton {
    private final static HBaseManager HBASE_MANAGER_INSTANCE = new HBaseManager(); 
}

关于java - 无法从 Tomcat 连接到 HBase,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46639560/

相关文章:

Java:找出通过channel.map和allocateDirect创建的ByteBuffer的区别

java - 如何杀死 quartz 预定线程?

java - 使用 spring/tomcat 的 http 请求响应不正确

spring - 如何跟踪 session 创建

java - 如何发送创建 JSON 字符串并将其从服务器发送到 android?

java - 根据其他属性的存在设置 Maven 属性

java - 我的 JSON 列表未显示在移动应用程序的 ListView 上,为什么?

java - 无法让 JavaFX 在 Eclipse 中工作

java - 在 Tomcat 上运行的 Jersey Servlet?

java - JSP将参数发送到表单操作字段中的servlet