远程链接HBase调试报错:Exception in thread "main" java.lang.ExceptionInInitializerError

本文记录了一次在CentOS6环境下,使用CDH5.7.0和HBase1.2.0进行外部连接时遇到的创建admin失败的问题。错误原因为缺少protobuf包,通过在pom文件中添加protobuf依赖成功解决了问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、问题描述

1.环境

CentOS6,CDH5.7.0,hbase-1.2.0-cdh5.7.0

2.报错描述

外部连接hbase服务器,在创建admin时报错:

String nameSpace = "Test";
        String tbName = "student";
        String colFamily = "info";
        // 1.读取配置文件
        //的hbase-default.xml,也可以把hbase-site.xml放到resources中
        Configuration conf = HBaseConfiguration.create();
        conf.set("hbase.rootdir","hdfs://hadoop01:8020/hbase");
        conf.set("hbase.zookeeper.quorum","hadoop01");
        conf.set("hbase.zookeeper.property.clientPort","2181");

        Connection connection;
        connection = ConnectionFactory.createConnection(conf);

        // 2.创建一个管理员,管理表格的创建和删除
//        HBaseAdmin admin = new HBaseAdmin(conf);
        Admin admin=connection.getAdmin();

报错:

19/04/10 09:03:20 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Exception in thread "main" java.lang.ExceptionInInitializerError
	at org.apache.hadoop.hbase.client.HConnectionKey.<init>(HConnectionKey.java:72)
	at org.apache.hadoop.hbase.client.ConnectionManager.getConnectionInternal(ConnectionManager.java:300)
	at org.apache.hadoop.hbase.client.HBaseAdmin.<init>(HBaseAdmin.java:231)
	at Hbase.HbaseUtils.main(HbaseUtils.java:24)
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
	at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:131)
	at org.apache.hadoop.security.Groups.<init>(Groups.java:78)
	at org.apache.hadoop.security.Groups.<init>(Groups.java:74)
	at org.apache.hadoop.security.Groups.getUserToGroupsMappingService(Groups.java:303)
	at org.apache.hadoop.security.Groups.getUserToGroupsMappingService(Groups.java:288)
	at org.apache.hadoop.hbase.security.UserProvider.<clinit>(UserProvider.java:56)
	... 4 more
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:129)
	... 9 more
Caused by: java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
	at org.apache.hadoop.util.PerformanceAdvisory.<clinit>(PerformanceAdvisory.java:23)
	at org.apache.hadoop.security.JniBasedUnixGroupsMappingWithFallback.<init>(JniBasedUnixGroupsMappingWithFallback.java:41)
	... 14 more
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 16 more

二、问题原因

把hbase-site.xml都放入了resources里面,而且使用的是CDH,所以兼容性基本排除。经过几天煎熬,竟然发现是少protobuf包,当把protobuf加入pom依赖,世界瞬间变美好了!

三、解决办法

添加pom依赖

<!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>2.5.0</version>
</dependency>

(大数据坑,一步一个踩!)

<think>我们正在解决一个具体的迁移问题:从MySQL到HBase迁移时出现java.lang.NoSuchMethodError错误,涉及HBaseAdmin类。根据错误信息,这通常是由于版本不兼容引起的,特别是HBase客户端代码使用的HBaseAdmin类中某个方法在运行时找不到。可能的场景:迁移工具或自定义代码在编译时使用了特定版本的HBase客户端库,但运行时使用了不同版本的HBase(或Hadoop)库。步骤分析:1.确认错误堆栈:首先,需要明确错误堆栈中指示的HBaseAdmin类的哪个方法找不到。例如,可能是某个HBaseAdmin的构造方法或实例方法。2.版本检查:检查项目中使用的HBase客户端库版本与目标HBase集群版本是否一致。同样,检查Hadoop版本,因为HBase依赖Hadoop。3.依赖冲突:检查项目依赖树,看是否有多个版本的HBaseHadoop库被引入,导致在运行时加载了错误版本的类。解决方案:1.统一版本:确保迁移工具或应用程序使用的HBase客户端版本与目标HBase集群的版本一致。例如,如果HBase集群是1.4.x,则客户端也应使用1.4.x。2.排除冲突依赖:如果项目依赖了其他组件(如Hive,Spark等)可能传递依赖了不同版本的HBase/Hadoop,需要在构建工具中排除冲突版本。以Maven为例:```xml<dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId><version>你的目标版本</version><exclusions><exclusion><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId></exclusion>...其他可能冲突的依赖</exclusions></dependency>```或者显式声明覆盖依赖版本。3.使用兼容API:考虑使用更高版本中被广泛支持的方法或使用其他类替代。例如,HBaseAdmin在较新版本中已被Admin接口取代(通过Connection.getAdmin()获得)。如果迁移工具使用的是旧版本的API,而目标集群版本较新,可能需要更新代码。4.检查Hadoop版本兼容性:HBaseHadoop版本有依赖关系,不同版本的HBase需要特定版本的Hadoop。请参考HBase官方文档的兼容性矩阵。5.具体错误示例:假设错误信息是`java.lang.NoSuchMethodError:org.apache.hadoop.hbase.client.HBaseAdmin.<init>(Lorg/apache/hadoop/conf/Configuration;)V`,这表示在运行时HBaseAdmin类没有接受Configuration参数的构造方法(这在旧版本中存在)。这通常是因为客户端代码编译时使用了旧版本(如0.98),而运行时使用的是新版本(如2.x),其中HBaseAdmin的构造方法发生了改变(例如,现在可能需要一个Connection对象)。在这种情况下,应该更新代码,使用新的API:```java//旧的用法(已过时)Configurationconfig=HBaseConfiguration.create();HBaseAdminadmin=newHBaseAdmin(config);//新的用法Connectionconnection=ConnectionFactory.createConnection(config);Adminadmin=connection.getAdmin();```6.如果由于某种原因不能升级代码,则可以考虑降级HBase客户端库版本以匹配目标集群。实际操作建议:-查看HBase集群的版本:在集群节点上执行`hbaseversion`命令。-在项目中明确指定HBase客户端版本,并确保排除其他版本的传递依赖。-运行迁移工具前,通过mvndependency:tree(或Gradle的依赖树命令)检查依赖冲突。注意:如果使用迁移工具(如ApacheSqoop或自定义工具),确保工具与目标HBase版本兼容。Sqoop1可能不支持最新版本的HBase,需要升级工具或使用其他迁移方法。总结:该错误的根本原因在于版本不兼容,解决方法主要是版本对齐和依赖管理。</think> ### 解决MySQL迁移到HBase时的NoSuchMethodError错误 该错误通常是由 **HBase/Hadoop依赖版本不匹配** 导致的。以下是完整解决方案: #### 🔧 错误根源分析 `java.lang.NoMethodError` 表示: 1. 编译环境与运行时环境的HBase客户端版本不一致[^1] 2. 不同HBase组件存在版本冲突(如HBaseAdmin类被替换) 3. Hadoop依赖与HBase版本不兼容[^2] #### ⚙️ 解决方案步骤 1. **统一HBase版本** ```gradle // Gradle示例:强制指定HBase版本 configurations.all { resolutionStrategy { force 'org.apache.hbase:hbase-client:2.4.9' // 需与实际集群版本一致 force 'org.apache.hbase:hbase-common:2.4.9' } } ``` 2. **使用HBaseAdmin替代方案** ```java // 新旧API对比 // 已废弃写法(导致错误) HBaseAdmin admin = new HBaseAdmin(config); // 正确写法(HBase 1.0+) Connection conn = ConnectionFactory.createConnection(config); Admin admin = conn.getAdmin(); ``` 3. **Hadoop版本兼容性检查** ```bash # 检查HadoopHBase兼容矩阵 $ hbase org.apache.hadoop.util.VersionInfo $ hadoop version # 官方兼容对照(示例): # HBase 2.4.x → Hadoop 3.x # HBase 1.4.x → Hadoop 2.7.x ``` 4. **依赖冲突检测** 使用Maven排查依赖树: ```bash mvn dependency:tree -Dincludes=org.apache.hbase ``` 若发现多版本共存,使用`<exclusion>`排除旧版本 #### 🛡️ 迁移最佳实践 1. **双重检查协议** ```java // 迁移前验证HBase配置 HBaseConfiguration.create().get("hbase.zookeeper.quorum"); ``` 2. **客户端版本锁定方案** ```xml <!-- Maven示例 --> <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-shaded-client</artifactId> <version>2.4.9</version> <!-- 使用shaded包避免冲突 --> </dependency> ``` 3. **迁移工具选择** - 使用官方推荐工具:**Apache Sqoop 1.4.7+** - 备份方案:**Spark HBase Connector** #### 📊 版本兼容性参考表 | HBase版本 | 兼容Hadoop | 客户端依赖 | |-----------|------------|------------| | 2.4.x | 3.3.0+ | hbase-client:2.4 | | 1.5.x | 2.10.x | hbase-client:1.5 | | CDH 6.x | CDH 6.3.3 | hbase-client:2.1.0-cdh6.3.3 | [^1]: 版本冲突是跨系统迁移常见问题。 [^2]: HadoopHBase的小版本差异常导致API变更。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值