我正在尝试在clojure中使用JIT编译来动态生成mapper和reducer类。但是,JobClient无法识别这些类(这是通常的ClassNotFoundException。)
如果我AOT编译Mapper,Reducer和Tool,并使用RunJar运行作业,一切似乎都很好。在查看source之后,似乎它正在解压缩jar并创建一个用于加载“main”实现的自定义URLClassLoader。我没有看到jar是如何跨节点分布的,甚至是如何在单节点集群中使用它。
非常感谢任何帮助!
答案 0 :(得分:4)
首先,当我们提交作业的jar时,它会被jobtracker复制到属性中配置的登台目录。当为tasktracker分配作业时(由调度程序ofc),它将从登台目录中复制并执行。
如果您希望使用Hadoop的分布式缓存工具来执行外部Jar执行,请执行此操作。
答案 1 :(得分:2)
Clojure与其他Java脚本方法(如Beanshell,Groovy和Ant)有一些共同之处...当你运行脚本时,如果你使用脚本语言的类加载功能,当你的脚本启动它时de - 从默认的类加载器中耦合自己,然后您的JVM在脚本引擎的自定义类加载器上运行。我不知道是什么导致了您的错误,但是您应该记住,如果您在脚本中执行任何操作会导致自定义类加载器放弃JVM默认类加载器,那么它可能会解释一些事情。
根据我的经验,我无法克服这些问题,因此,例如,使用Beanshell,我不得不停止使用类加载器选项并在启动JVM的命令行上指定我的整个类路径。这样我知道脚本使用了默认的类加载器,并且可以找到所有类。
另一个例子,有:
类/常规/ A.groovy
类/常规/ B.groovy
public class A {
public A() {
B b = new B()
}
}
GroovyClassLoader不会加载Groovy类B.尝试从自定义类加载器(而不是默认的类加载器)中加载带有classForName的JDBC驱动程序时,也可以重现这种类型的东西。