【问题标题】:Exception when Servlet try to run Hadoop 2.2.0 MapReduce JobServlet 尝试运行 Hadoop 2.2.0 MapReduce 作业时出现异常
【发布时间】:2014-05-10 22:49:04
【问题描述】:

已解决(解决方案在 cmets 中)

我在 ubuntu 13.10 和 Eclipse Kepler v4.3 上使用 Hadoop 2.2.0(伪分布式模式)来开发我的 Hadoop 程序和动态 Web 项目 (没有 Maven)。

我的 Hadoop jar 项目名为“WorkTest.jar”,当我使用“Hadoop jar WorkTest.jar”从命令行运行作业时,它可以正常工作,并且我在终端上正确地看到了工作进度。

Hadoop项目包含四个要素:

  • DriverJob.java(配置和启动作业的类)
  • Mapper.java
  • Combiner.java
  • Reducer.java

现在我用 ServletTest.java 编写了一个新的动态 Web 项目,在其中我输入了 DriverJob 类代码,其他类(Mapper.java、Combiner.java、Reducer.java)是与servlet(主包)放在同一个包中。 WebContent/lib 文件夹包含所有 Hadoop jar 必需的依赖项。

我已经成功地在 WildFly 8 Server whit Eclipse 上部署了我的应用程序,但是当我尝试运行 mapreduce 作业(作业配置成功运行并且我设法在 HDFS 上删除并写入一个文件夹)时,他继续失败并出现以下异常从 Hadoop 作业日志文件中可见:

FATAL [IPC Server handler 5 on 46834] org.apache.hadoop.mapred.TaskAttemptListenerImpl: Task: attempt_1396015900746_0023_m_000002_0 - exited : java.lang.RuntimeException: java.lang.ClassNotFoundException: Class Mapper not found
    at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:1720)
    at org.apache.hadoop.mapreduce.task.JobContextImpl.getMapperClass(JobContextImpl.java:186)
    at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:721)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:339)
    at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:162)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:415)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491)
    at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:157)
Caused by: java.lang.ClassNotFoundException: Class Mapper not found
    at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:1626)
    at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:1718)
    ... 8 more

来自 WildFly 日志文件:

WARN  [org.apache.hadoop.mapreduce.JobSubmitter] Hadoop command-line option parsing not performed. Implement the Tool interface and execute your application with ToolRunner to remedy this.
WARN  [org.apache.hadoop.mapreduce.JobSubmitter] No job jar file set.  User classes may not be found. See Job or Job#setJar(String).

但是 WildFly 上的 WEB-INF/classes/ deploy 文件夹包含 Mapper.class、Combiner.class 和 Reducer.class。

我也试过在servlet里面输入Mapper、Combiner和Reducer的类代码,但是还是不行,报同样的错误……

我做错了什么?

【问题讨论】:

    标签: java eclipse servlets hadoop wildfly


    【解决方案1】:

    我相信您需要将您的 .class 文件保存在可以分发到集群中的节点的存档 (jar) 中。

    WARN  [org.apache.hadoop.mapreduce.JobSubmitter] No job jar file set.  User classes may not be found. See Job or Job#setJar(String).
    

    这个错误是关键。通常你会使用job.setJarByClass(DriverJob.class) 告诉mapreduce 客户端哪个jar 文件有Mapper/Reducer 类。您没有 jar,因此分发适当类的方法分崩离析。

    【讨论】:

    • 感谢您的回复。我改变了我的方法:我从我的 ServletTest 中删除了 DriverJob 代码,并将 Hadoop jar (WorkTest.jar) 放在 WEB-INF/lib 文件夹中。在我的 DriverJob.java 中我设置了:job.setJarByClass(jobexecutor.DriverJob.class); job.setMapperClass(jobexecutor.Mapper.class); job.setCombinerClass(jobexecutor.Combiner.class); job.setReducerClass(jobexecutor.Reducer.class); 现在我只从 servlet 调用 DriverJob 方法String output = jobexecutor.DriverJob.run(String inputData);但是当我尝试运行 mapreduce 作业时,他一直以同样的异常失败......
    • 我可能已经找到了问题的原因:如果我在 DriverJob 类的内部运行 job.getJar(); 方法,这将返回一个 null 值!为什么?
    • 而mapper/reducer类在这个WorkTest.jar?
    • 另外,请确保您的类路径中的某处没有该类文件的任何挥之不去的实例
    • 是的,mapper/reducer 类在WorkTest.jar。我设法通过在DriverJob.java 中使用config.set("mapreduce.job.jar", "full_path_of_my_jobexecutor.jar_in_my_deploy_folder_on_wildfly"); 解决了这个问题。问题是 job.setJarByClass(jobexecutor.DriverJob.class) 方法无法找到包含它的包...我强制声明,错误消失了!
    猜你喜欢
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    • 2014-07-28
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多