运行使用Hadoop流时,通过脚本的Java应用程序:java.lang.NoClassDefFou

2019-09-22 01:28发布

我用的Hadoop流的tcsh中执行一个脚本文件:

-- First copy the jar files to the Hadoop filesystem,
   so that they are next to inputdir and outputdir. --
cp App/* /hadoop/jardir/

-- Run Hadoop --
hadoop jar /usr/lib/hadoop/contrib/streaming/hadoop-streaming-0.20.2-cdh3u4.jar \\
-D mapred.task.timeout=120000000 \\
-input "/hadoop/inputdir/" -output "/hadoop/outputdir/" \\
-mapper script.sh -reducer script.sh -file script.sh \\
-jobconf mapred.map.tasks=1 -jobconf mapred.reduce.tasks=0 >>& log.txt

该脚本文件调用Java的是这样的:

java -cp /hadoop/jardir/SomeJavaApp.jar:/hadoop/jardir/* some.JavaApplication

即使我明确地告诉Java的类路径,运行它失败:

Exception in thread "main" java.lang.NoClassDefFoundError: some/JavaApplication
Caused by: java.lang.ClassNotFoundException: some.JavaApplication
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Could not find the main class: some.JavaApplication.  Program will exit.

我已经尝试过,如设置Hadoops各种建议-libjars参数,但这并没有帮助。

我如何使用Hadoop流运行时通过脚本的Java应用程序?

Answer 1:

我认为问题是,你的罐子不会被复制到分布式缓存。 尝试船罐子通过shell脚本一起-files选项。 例如:

hadoop jar /home/user/hadoop-distrib/lib/hadoop-streaming.jar \
    -files runjava.sh,hadooptest.jar  \
    -D mapreduce.job.reduces=0 \
    -D mapred.job.name=TestJob \
    -input /user/hadoop/test \
    -output /user/hadoop/test/res \
    -mapper 'runjava.sh'

我假设你是从哪里目录中运行你的数据流作业hadooptest.jarrunjava.sh存储。

runjava.sh:

java -cp /home/user/test/hadooptest.jar:/home/user/hadoop-distrib/lib/* com.example.hadooptest.StreamTest


StreamTest.java:

...
public class StreamTest {

    public static void main(String[] args) throws Exception {

        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String s = null;
        while ((s = in.readLine()) != null && s.length() != 0) {
            System.out.println(s);
        }
    }
}

这个例子正常工作在版本0.20,追加-r1056497。



文章来源: Running a Java application via a script when using Hadoop Streaming: java.lang.NoClassDefFoundError