我有一个servlet项目,我将hbase-x.x.x.jar
和hadoop-x.x.x.jar
放到WebContent/Web-INF/lib
目录中,这些API在编译期间可用。
应该在处理POST请求时对HBase进行写入。
这是我的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
答案 0 :(得分:0)
继续发表评论帖,因为SO抱怨评论过多。
如果您从eclipse中跑出来,您确定这些罐子正在出口吗?尝试转到项目属性 - &gt; Java构建路径并将2个jar作为库添加,并将它们标记为导出。
您似乎有一个范围问题:
private static class HBaseManagerSingleton {
private final static HBaseManager HBASE_MANAGER_INSTANCE = new HBaseManager();
}