Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在同一程序中处理两个版本的Hadoop时,Hadoop jar冲突问题_Java_Maven_Hadoop_Hbase - Fatal编程技术网

Java 在同一程序中处理两个版本的Hadoop时,Hadoop jar冲突问题

Java 在同一程序中处理两个版本的Hadoop时,Hadoop jar冲突问题,java,maven,hadoop,hbase,Java,Maven,Hadoop,Hbase,下面是我们遇到的当前Hadoop不兼容问题 用例 我们正在读取/扫描运行在新Hadoop(版本2.2.0.2.0.6.0-101[Hortonworks])上的HBASE(版本0.96.1.2.0.1-101-hadoop2),并使用JAVA程序写入旧Hadoop(版本0.20.2+320[Cloudera])。 但是,由于两个Hadoop版本之间的不兼容,我们遇到了异常 以下代码段引发异常: private HbaseConfigFactory(String clusterUri, Strin

下面是我们遇到的当前Hadoop不兼容问题

用例

我们正在读取/扫描运行在新Hadoop(版本2.2.0.2.0.6.0-101[Hortonworks])上的HBASE(版本0.96.1.2.0.1-101-hadoop2),并使用JAVA程序写入旧Hadoop(版本0.20.2+320[Cloudera])。 但是,由于两个Hadoop版本之间的不兼容,我们遇到了异常

以下代码段引发异常:

private HbaseConfigFactory(String clusterUri, String hbaseRootdir) throws Exception {
    factoryImpl = HBaseConfiguration.create();
    factoryImpl.clear();

    factoryImpl.set("hbase.zookeeper.quorum", clusterUri);
    factoryImpl.set("zookeeper.znode.parent", hbaseRootdir);

    // set the zookeeper port
    String[] eles = clusterUri.split(":");
    if (eles.length > 1) {
        factoryImpl.set("hbase.zookeeper.property.clientPort", eles[1]);
    }

    try {
    //THE BELOW CODE CAUSE THE EXCEPTION
          HBaseAdmin.checkHBaseAvailable(factoryImpl);

    } catch (Exception e) {
        String message = String.format("HBase is currently unavailable: %s, %s",
                e.getMessage(), e);
        logger.error(message);

        throw new Exception(e);
    }

}
以下是例外情况:

private HbaseConfigFactory(String clusterUri, String hbaseRootdir) throws Exception {
    factoryImpl = HBaseConfiguration.create();
    factoryImpl.clear();

    factoryImpl.set("hbase.zookeeper.quorum", clusterUri);
    factoryImpl.set("zookeeper.znode.parent", hbaseRootdir);

    // set the zookeeper port
    String[] eles = clusterUri.split(":");
    if (eles.length > 1) {
        factoryImpl.set("hbase.zookeeper.property.clientPort", eles[1]);
    }

    try {
    //THE BELOW CODE CAUSE THE EXCEPTION
          HBaseAdmin.checkHBaseAvailable(factoryImpl);

    } catch (Exception e) {
        String message = String.format("HBase is currently unavailable: %s, %s",
                e.getMessage(), e);
        logger.error(message);

        throw new Exception(e);
    }

}
java.lang.Exception:java.lang.IllegalArgumentException:在org.apache.hadoop.security.UserGroupInformation中找不到方法getCurrentUser! 在com.shopping.writetold.HbaseConfigFactory.(HbaseConfigFactory.java:36) 位于com.shopping.writetold.HbaseConfigFactory.getInstance(HbaseConfigFactory.java:48) 位于com.shopping.writetold.WriteToHDFS.readDeals(WriteToHDFS.java:63) 位于com.shopping.writetold.WriteToHDFS.main(WriteToHDFS.java:50) 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处 在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)中 在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中 位于java.lang.reflect.Method.invoke(Method.java:601) 位于com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 原因:java.lang.IllegalArgumentException:在org.apache.hadoop.security.UserGroupInformation中找不到方法getCurrentUser! 位于org.apache.hadoop.hbase.util.Methods.call(Methods.java:45) 位于org.apache.hadoop.hbase.security.User.call(User.java:414) 位于org.apache.hadoop.hbase.security.User.callStatic(User.java:404) 位于org.apache.hadoop.hbase.security.User.access$200(User.java:48) 位于org.apache.hadoop.hbase.security.User$SecureHadoopUser。(User.java:221) 位于org.apache.hadoop.hbase.security.User$SecureHadoopUser。(User.java:216) 位于org.apache.hadoop.hbase.security.User.getCurrent(User.java:139) 位于org.apache.hadoop.hbase.client.HConnectionKey.(HConnectionKey.java:67) 位于org.apache.hadoop.hbase.client.HConnectionManager.getConnection(HConnectionManager.java:240) 位于org.apache.hadoop.hbase.client.HBaseAdmin.checkHBaseAvailable(HBaseAdmin.java:2321) 在com.shopping.writetold.HbaseConfigFactory.(HbaseConfigFactory.java:29) ... 8个以上 原因:java.lang.NoSuchMethodException:org.apache.hadoop.security.UserGroupInformation.getCurrentUser() 位于java.lang.Class.getMethod(Class.java:1624) 位于org.apache.hadoop.hbase.util.Methods.call(Methods.java:38) ... 还有18个

Maven依赖项:

  <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-core</artifactId>
        <version>0.20.2</version>
    </dependency>

    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-client</artifactId>
        <version>0.96.0-hadoop2</version>
    </dependency>

org.apache.hadoop
hadoop内核
0.20.2
org.apache.hbase
hbase客户端
0.96.0-hadoop2
罐子细节 Maven:org.apache.hadoop:hadoop-common:2.1.0-beta hadoop-common-2.1.0-beta.jar

类文件UserGroupInformation中的方法签名 public static synchronized org.apache.hadoop.security.UserGroupInformation getCurrentUser()抛出java.io.IOException

罐子细节 Maven:org.apache.hadoop:hadoop核心:0.20.2 hadoop-core-0.20.2.jar

类文件UserGroupInformation中的方法签名 静态javax.security.auth.Subject getCurrentUser()

两者具有相同的名称空间,即: 包org.apache.hadoop.security

当我有单独的程序从hbase读取数据并只使用各自的JAR写入cloudera HDFS时,它们工作得很好

在单个程序中是否有处理上述不兼容的解决方案

谢谢
Sagar B

免责声明:作为先决条件,我认为更新到最新的统一Hadoop库是不可能的,但我对Hadoop几乎一无所知

本质上,您处于冲突中,因为在运行时,需要在类路径上同时使用两个库,这是一项艰巨的任务。为了在同一个VM中有两个来自不同来源的相同类,您需要至少使用两个不同的类加载器

从技术/架构的角度来看,在这个场景中要做的事情是将应用程序的两个部分解耦。或者在同一个VM中使用不同的类加载器运行,或者实际上将其作为使用共享机制交换消息的异构程序进行解耦(我想到了jms,但有很多替代方案)

由于您想探索单一虚拟机问题,因此面临两种选择。 手动执行或使用支持此操作的应用程序容器(OSGI)。无论哪种情况,您都需要至少在maven中解耦应用程序,以区分它们的依赖关系等

手动将意味着将应用程序的一部分放在当前类加载器中,然后从自定义类加载器中加载第二部分,因此假设写部分卸载在一个单独的jar中,创建一个自定义clasloader,加载旧的Hadoop jar(以及适用的转换)和这个单独的jar文件。相当技术性,但可行

我发现了一个使用java.util.ServiceLoader的参考问题,该问题可能会突出主题“使用自担风险”。()


另一个实际上正是出于这个原因而起作用的解耦解决方案是OSGI模型,它允许jar在pier层次结构中拥有自己独立的运行时依赖树,这本质上意味着同一个类可能存在于vm的多个版本中,因为它是每个jar的一个类加载器。然而,由于许多其他原因,OSGI是另一个猛兽,需要花费相当大的学习努力才能真正理解和利用。

最好包括maven依赖树(mvn dependency:tree)的相关部分。您解决了这个问题吗?你能更新你的解决方案吗?非常感谢