Hadoop的RunJar方法如何跨节点分发类/ jar文件?

Jie*_*ren 8 java jit hadoop clojure

我正在尝试在clojure中使用JIT编译来动态生成mapper和reducer类.但是,JobClient无法识别这些类(这是通常的ClassNotFoundException.)

如果我AOT编译Mapper,Reducer和Tool,并使用RunJar运行作业,一切似乎都很好.在查看源代码之后,似乎它正在解压缩jar并创建一个自定义URLClassLoader,用于加载"main"实现.我没有看到jar是如何跨节点分布的,甚至是如何在单节点集群中使用它.

任何帮助将非常感激!

dja*_*fan 2

Clojure 与其他 Java 脚本方法(例如 Beanshell、Groovy 和 Ant)有一些共同点,即当您运行脚本时,如果您使用脚本语言的类加载功能,那么当您的脚本启动时,它会自行解耦从默认的类加载器中加载,然后您的 JVM 在脚本引擎的自定义类加载器上运行。我不知道是什么导致了你的错误,但你应该记住,如果你在脚本中做了任何会导致自定义类加载器放弃 JVM 默认类加载器的事情,那么它可能会解释一些事情。

根据我的经验,我无法克服这些问题,因此,例如,使用 Beanshell,我必须停止使用类加载器选项,并在启动 JVM 的命令行上指定整个类路径。这样我就知道脚本使用了默认的类加载器并且所有的类都会被找到。

另一个例子:

类/groovy/A.groovy

类/groovy/B.groovy

 public class A {
    public A() {
       B b = new B()
    }
 }
Run Code Online (Sandbox Code Playgroud)

GroovyClassLoader 不会加载 Groovy 类 B。尝试从自定义类加载器(不是默认类加载器)中加载带有 classForName 的 JDBC 驱动程序也可以重现这种类型的情况。