【问题标题】:ClassNotFoundException when running hadoop jar运行 hadoop jar 时出现 ClassNotFoundException
【发布时间】:2016-01-07 03:48:49
【问题描述】:

我正在尝试从 jar 文件运行 MapReduce 作业并不断收到 ClassNotFoundException 错误。我在 Centos 6 虚拟机上运行 Hadoop 1.2.1。

首先我使用以下shell脚本compile.sh将文件exercise.java(和类)编译成一个jar文件exercise.jar

#!/bin/bash

javac -classpath /pathto/hadoop-common-1.2.1.jar:\
/pathto/hadoop-core-1.2.1.jar /pathto/exercise.java

jar cvf exercise.jar /pathto/*.class

这运行良好,jar 成功完成。然后我尝试使用 shell 脚本 exec.sh 运行实际的 MapReduce 作业:

#!/bin/bash

export CLASSPATH=$CLASSPATH:/pathto/hadoop-common-1.2.1.jar:\
/pathto/hadoop-core-1.2.1.jar:/pathto/exercise.class

hadoop jar exercise.jar exercise /data/input/inputfile.txt /data/output

这会引发ClassNotFoundException 错误:

Exception in thread "main" java.lang.ClassNotFoundException: exercise
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:274)
    at org.apache.hadoop.util.RunJar.main(RunJar.java:153) 

我意识到明确的路径名可能不是必需的,但我有点不顾一切地仔细检查所有内容。我已通过job.setJarByClass(exercise.class); 确认在我的exercise.java 文件中exercise.class 在作业配置中,并确认exercise.class 包含在exercise.jar 中。好像没看懂。

更新 exec.sh 脚本的完整路径为exercise.class。它存储在我的 Eclipse 项目目录中:

#!/bin/bash

export CLASSPATH=$CLASSPATH:/pathto/hadoop-common-1.2.1.jar:\
/pathto/hadoop-core-1.2.1.jar:/home/username/workspace/MVN_Hadoop/src/main/java.com.amend.hadoop.MapReduce/*

hadoop jar \
exercise.jar \
/home/username/workspace/MVN_Hadoop/src/main/java.com.amend.hadoop.MapReduce/exercise \
/data/input/inputfile.txt \
/data/output

当我实际尝试使用显式写出的路径名运行 exec.sh 脚本时,我也会得到一组完全不同的错误:

Exception in thread "main" java.lang.ClassNotFoundException: /home/hdadmin/workspace/MVN_Hadoop/src/main/java/come/amend/hadoop/MapReduce/exercise
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:274)
    at org.apache.hadoop.util.RunJar.main(RunJar.java:153) 

【问题讨论】:

  • 如果您遵循 Java 约定,该类可能在 exercise.java 内定义为 Exercise。尝试做hadoop jar exercise.jar Exercise /data/input/inputfile.txt /data/output(大写E
  • 你不应该使用/home/username/workspace/MVN_Hadoop/src/main/java.com.amend.hadoop.MapReduce/exercise,因为那是你的本地文件系统而不是Java类文件
  • @cricket_007 我最初并没有这样做,只是按照下面 srikanth 的要求把它放在那里。如果我删除它,仍然会得到原来的错误......
  • 是的,您会收到不同的错误,因为您的 JAR 文件不包含该路径。就像我说的那样,这是您的本地磁盘,HDFS 和 JAR 都知道如何读取。 jar 文件后面的参数只需要是 JAR 文件中包含的类文件的名称即可。您可以提供包名称,但不能提供磁盘上的位置。
  • @cricket_007 我明白你在说什么,但如果我把它保留为 'hadoop jar exercise.jar exercise /data/input/inputfile.txt /data/output' (练习是jar 文件中类的名称)我仍然得到原始错误。

标签: java hadoop jar mapreduce


【解决方案1】:

我可以看到这个可能的错误。 从 Hadoop jar exercise.jar 练习 /data/input/inputfile.txt /data/output 请指定练习类的完整路径。即 org.name.package.exercise 如果存在。要交叉检查,请打开 jar 文件并检查executive.class 的位置。 继续,Hadoop 不希望 jar 包含在 jar 中,因为 Hadoop 的路径是全局设置的。

新: 看,下面的路径有些奇怪。 "/home/hdadmin/workspace/MVN_Hadoop/src/main/java/come/amend/hadoop/MapReduce/exercise"

如果您使用 jar 运行,那么类路径怎么会如此具体,而不是 jar 路径。只能是“来/修改/hadoop/MapReduce/exercise”这个。

【讨论】:

  • 抱歉回复晚了,但我根据您的要求更新了我的问题。谢谢!
猜你喜欢
  • 2014-07-21
  • 1970-01-01
  • 1970-01-01
  • 2013-04-26
  • 1970-01-01
  • 1970-01-01
  • 2013-11-14
  • 1970-01-01
  • 2016-07-26
相关资源
最近更新 更多