此页面上的内容需要较新版本的 Adobe Flash Player。

获取 Adobe Flash Player

您现在的位置: 智可网 - 新技术 - Hadoop - 正文
Hadoop:客户端提交作业时发生的一个常见错误
教程录入:李隆权    责任编辑:quan 作者:佚名 文章来源:656463
很多朋友在刚开始学习Hadoop的时候,都会以类似于下面的一个例子来开始自己的hadoop学习之旅:
public class MyHadoopCounter {
 
 public static class MyHadoopMapper extends Mapper<LongWritable, Text, Text, Text> {
  
  @Override
  protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
   System.out.println(" ===== " + value);
   context.write(new Text("Info"), value);
  }
 }
 
 public static void main(String[] args) throws Exception {
  Configuration conf = new Configuration();
  conf.addResource("core-site.XML");
  
  Job myJob = new Job(conf, "MyJob");
  myJob.setJarByClass(MyHadoopCounter.class);
  myJob.setMapperClass(MyHadoopMapper.class);
  
  FileInputFormat.addInputPath(myJob, new Path("data"));
  FileOutputFormat.setOutputPath(myJob, new Path("out1"));
  
  System.exit(myJob.waitForCompletion(true) ? 0 : 1);
  
 }
}

(注:这个例子是我拷贝一位网友的)

然后,系统抛出了异常:
2011-12-17 17:17:37,912 INFO org.apache.hadoop.mapred.TaskInProgress: Error from attempt_201112171704_0004_m_000000_0: java.lang.RuntimeException: Java.lang.ClassNotFoundException: com.xkq.hadoop.counter.MyHadoopCounter$MyHadoopMapper
 at org.apache.hadoop.conf.Configuration.getClass(Configuration.Java:866)
 at org.apache.hadoop.mapreduce.JobContext.getMapperClass(JobContext.Java:199)
 at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.Java:719)
 at org.apache.hadoop.mapred.MapTask.run(MapTask.Java:370)
 at org.apache.hadoop.mapred.Child$4.run(Child.Java:261)
 at Java.security.AccessController.doPrivileged(Native Method)
 at javax.security.auth.Subject.doAs(Subject.Java:396)
 at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.Java:1059)
 at org.apache.hadoop.mapred.Child.main(Child.Java:255)
Caused by: Java.lang.ClassNotFoundException: com.xkq.hadoop.counter.MyHadoopCounter$MyHadoopMapper
 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)
 at Java.lang.Class.forName0(Native Method)
 at java.lang.Class.forName(Class.Java:247)
 at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.Java:819)
 at org.apache.hadoop.conf.Configuration.getClass(Configuration.Java:864)
 ... 8 more
2011-12-17 17:17:40,921 INFO org.apache.hadoop.mapred.JobTracker: Removing task 'attempt_201112171704_0004_m_000000_0'
2011-12-17 17:17:41,122 INFO org.apache.hadoop.mapred.JobInProgress: Choosing a failed task task_201112171704_0004_m_000000

我可以肯定这个异常绝大多数初学者都遇到过,所以我想说,你们遇到这个尴尬的问题是因为你们不懂Hadoop的源码。下面我来好好分析这个问题。

首先我想先说一个这个配置文件的加载,其实这位网友的conf.addResource("core-site.XML")Configuration conf = new Configuration()之后根本就是多此一举,因为为在Configuration 类的静态代码中加入了


另外,在JobConf类的静态代码中也加入了

也就是说,Job的配置文件已经会默认包含core-default.XMLcore-site.XML、mapred-default.XML、mapred-site.XML,这里还要特别注意的是,如果你不想要这些默认的配置文件,当你创建时应该这样

//false表示忽略默认的配置文件,true表示加载默认的配置文件,默认情况下是true

Configuration conf = new Configuration(false);

好,现在就来看看出现上面异常的原因,这个问题主要出在myJob.setJarByClass(MyHadoopCounter.class)这条语句的本质是想获取MyHadoopCounter所在的jar包绝对路径,然后把这个绝对路径配置到作业的maprd.jar项,如果当前project中没有MyHadoopCounter所在的jar包的话,作业的配置文件中就没有maprd.jar项,当TaskTracker在执行该作业的任务时就找不到MyHadoopCounter类了,因此也就出现了上面的异常。

解决办法:

   1.将上面的而是代码打成一个jar包,并将其引入加到当前工程中。

   2.在客户端的配置文件mapred.site.XML中配置

   <property>

        <name>maprd.jar</name>

        <value>MyHadoopCounter所在jar包的绝对路径</value>

   </property>

分享
打赏我
打开支付宝"扫一扫" 打开微信"扫一扫"
客户端
"扫一扫"下载智可网App
意见反馈
Hadoop:客户端提交作业时发生的一个常见错误
作者:佚名 来源:656463
很多朋友在刚开始学习Hadoop的时候,都会以类似于下面的一个例子来开始自己的hadoop学习之旅:
public class MyHadoopCounter {
 
 public static class MyHadoopMapper extends Mapper<LongWritable, Text, Text, Text> {
  
  @Override
  protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
   System.out.println(" ===== " + value);
   context.write(new Text("Info"), value);
  }
 }
 
 public static void main(String[] args) throws Exception {
  Configuration conf = new Configuration();
  conf.addResource("core-site.XML");
  
  Job myJob = new Job(conf, "MyJob");
  myJob.setJarByClass(MyHadoopCounter.class);
  myJob.setMapperClass(MyHadoopMapper.class);
  
  FileInputFormat.addInputPath(myJob, new Path("data"));
  FileOutputFormat.setOutputPath(myJob, new Path("out1"));
  
  System.exit(myJob.waitForCompletion(true) ? 0 : 1);
  
 }
}

(注:这个例子是我拷贝一位网友的)

然后,系统抛出了异常:
2011-12-17 17:17:37,912 INFO org.apache.hadoop.mapred.TaskInProgress: Error from attempt_201112171704_0004_m_000000_0: java.lang.RuntimeException: Java.lang.ClassNotFoundException: com.xkq.hadoop.counter.MyHadoopCounter$MyHadoopMapper
 at org.apache.hadoop.conf.Configuration.getClass(Configuration.Java:866)
 at org.apache.hadoop.mapreduce.JobContext.getMapperClass(JobContext.Java:199)
 at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.Java:719)
 at org.apache.hadoop.mapred.MapTask.run(MapTask.Java:370)
 at org.apache.hadoop.mapred.Child$4.run(Child.Java:261)
 at Java.security.AccessController.doPrivileged(Native Method)
 at javax.security.auth.Subject.doAs(Subject.Java:396)
 at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.Java:1059)
 at org.apache.hadoop.mapred.Child.main(Child.Java:255)
Caused by: Java.lang.ClassNotFoundException: com.xkq.hadoop.counter.MyHadoopCounter$MyHadoopMapper
 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)
 at Java.lang.Class.forName0(Native Method)
 at java.lang.Class.forName(Class.Java:247)
 at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.Java:819)
 at org.apache.hadoop.conf.Configuration.getClass(Configuration.Java:864)
 ... 8 more
2011-12-17 17:17:40,921 INFO org.apache.hadoop.mapred.JobTracker: Removing task 'attempt_201112171704_0004_m_000000_0'
2011-12-17 17:17:41,122 INFO org.apache.hadoop.mapred.JobInProgress: Choosing a failed task task_201112171704_0004_m_000000

我可以肯定这个异常绝大多数初学者都遇到过,所以我想说,你们遇到这个尴尬的问题是因为你们不懂Hadoop的源码。下面我来好好分析这个问题。

首先我想先说一个这个配置文件的加载,其实这位网友的conf.addResource("core-site.XML")Configuration conf = new Configuration()之后根本就是多此一举,因为为在Configuration 类的静态代码中加入了


另外,在JobConf类的静态代码中也加入了

也就是说,Job的配置文件已经会默认包含core-default.XMLcore-site.XML、mapred-default.XML、mapred-site.XML,这里还要特别注意的是,如果你不想要这些默认的配置文件,当你创建时应该这样

//false表示忽略默认的配置文件,true表示加载默认的配置文件,默认情况下是true

Configuration conf = new Configuration(false);

好,现在就来看看出现上面异常的原因,这个问题主要出在myJob.setJarByClass(MyHadoopCounter.class)这条语句的本质是想获取MyHadoopCounter所在的jar包绝对路径,然后把这个绝对路径配置到作业的maprd.jar项,如果当前project中没有MyHadoopCounter所在的jar包的话,作业的配置文件中就没有maprd.jar项,当TaskTracker在执行该作业的任务时就找不到MyHadoopCounter类了,因此也就出现了上面的异常。

解决办法:

   1.将上面的而是代码打成一个jar包,并将其引入加到当前工程中。

   2.在客户端的配置文件mapred.site.XML中配置

   <property>

        <name>maprd.jar</name>

        <value>MyHadoopCounter所在jar包的绝对路径</value>

   </property>