首页 > 其他 > 详细

使用JNI获取hadoop 2.6版本显示Unknown

时间:2021-06-10 17:36:46      阅读:28      评论:0      收藏:0      [点我收藏+]

问题:

c++通过JNI调用hive-jdbc连接hive-server,当hadoop版本为2.6时,总是报错

技术分享图片

 

Illegal Hadoop Version: Unknown (expected A.B.* format)

 

原因:

hadoop 2.6 获取版本源码如下(hadoop 3.x 版本修改了此代码,所以不会遇到此问题):

  protected VersionInfo(String component) {
    info = new Properties();
    String versionInfoFile = component + "-version-info.properties";
    InputStream is = null;
    try {
      is = Thread.currentThread().getContextClassLoader()
        .getResourceAsStream(versionInfoFile);
      if (is == null) {
        throw new IOException("Resource not found");
      }
      info.load(is);
    } catch (IOException ex) {
      LogFactory.getLog(getClass()).warn("Could not read ‘" +
          versionInfoFile + "‘, " + ex.toString(), ex);
    } finally {
      IOUtils.closeStream(is);
    }
  }

 

调用了函数 getContextClassLoader 获取classloader来加载hadoop版本信息文件,这个函数默认获取到的是system class loader,但是在JNI中使用了函数AttachCurrentThread,函数getContextClassLoader 获取到的将是 bootstrap class loader,加载文件错误,所以会抛出获取hadoop版本异常 

Java Native Interface Specification: 5 - The Invocation API (oracle.com)

 

AttachCurrentThread

jint AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args);

Attaches the current thread to a Java VM. Returns a JNI interface pointer in the JNIEnv argument.

Trying to attach a thread that is already attached is a no-op.

A native thread cannot be attached simultaneously to two Java VMs.

When a thread is attached to the VM, the context class loader is the bootstrap loader.

 

解决方法:

连接hive之前先调用函数 setContextClassLoader 重新设置 context loader

java.lang.Thread.currentThread().setContextClassLoader(
    java.lang.ClassLoader.getSystemClassLoader()
);

  

使用JNI获取hadoop 2.6版本显示Unknown

原文:https://www.cnblogs.com/kouruyi/p/14871276.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!