hadoop错误之ClassNotFoundException

本文介绍了在开发环境中遇到Hadoop的ClassNotFoundException问题,并分享了解决方案。作者在使用hadoop 1.2.1、eclipse Juno Service Release 2和JDK 1.7时,发现wordCount程序在Ubuntu上运行正常,但在Windows环境下需要特定设置。解决步骤包括在代码中添加job.setJarByClass(),以及设置conf.set("mapred.jar")指向jar包路径。虽然仍有些繁琐,但避免了频繁在不同系统间切换。作者也提供了参考链接以供深入理解问题原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开发环境: 

hadoop 1.2.1

eclipse Version: Juno Service Release 2

JDK 1.7

ubuntu 12.04LTS


代码:

下面的代码本质上就是一个wordCount程序


package org.conan.myhadoop.mr;

import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;

public class WordCount {

    public static class WordCountMapper extends Mapper<Object, Text, Text, IntWritable> {
        private final static IntWritable one = new IntWritable(1);
        private Text word = new Text();

        @Override
        public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
            StringTokenizer itr = new StringTokenizer(value.toString());
            while (itr.hasMoreTokens()) {
                word.set(itr.nextToken());
                context.write(word, one);
            }

        }
    }

    public static class WordCountReducer extends Reducer<Text,IntWritable,Text,IntWritable> {
        private IntWritable result = new IntWritable();

        @Override
        public void reduce(Text key, Iterable<IntWritable> values,Context context) throws IOException, InterruptedException {
        	int sum = 0;
        	for (IntWritable val : values) {
        	sum += val.get();
        	}
        	result.set(sum);
        	context.write(key, result);
        }
    }

    public static void main(String[] args) throws Exception {
        String input = "hdfs://192.168.56.101:9000/user/hdfs/o_t_account";
        String output = "hdfs://192.168.56.101:9000/user/hdfs/o_t_account/result";

        Configuration conf = new Configuration();
        
        //conf.set("mapred.jar", "C:/Users/exinglo/Documents/DigDig/Hadoop/myHadoop/myHadoop.jar");
        //conf.set("hadoop.job.user", "hadoop");
        //conf.addResource("classpath:/hadoop/core-site.xml");
        //conf.addResource("classpath:/hadoop/hdfs-site.xml");
        //conf.addResource("classpath:/hadoop/mapred-site.xml");

        //conf.set("fs.default.name", "hdfs://192.168.56.101:9000");
        //conf.set("mapred.job.tracker", "192.168.56.101:9001");
        Job job = new Job(conf, "word count");
        job.setJarByClass(WordCount.class);
        job.setMapperClass(WordCountMapper.class);
        job.setCombinerClass(WordCountReducer.class);
        job.setReducerClass(WordCountReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        FileInputFormat.addInputPath(job, new Path(input));
        FileOutputFormat.setOutputPath(job, new Path(output));
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }

}

错误输出:

Mar 16, 2014 4:00:40 PM org.apache.hadoop.mapred.JobClient copyAndConfigureFiles
WARNING: Use GenericOptionsParser for parsing the arguments. Applications should implement Tool for the same.
Mar 16, 2014 4:00:40 PM org.apache.hadoop.mapred.JobClient copyAndConfigureFiles
WARNING: No job jar file set.  User classes may not be found. See JobConf(Class) or JobConf#setJar(String).
Mar 16, 2014 4:00:40 PM org.apache.hadoop.mapreduce.lib.input.FileInputFormat listStatus
INFO: Total input paths to process : 1
Mar 16, 2014 4:00:40 PM org.apache.hadoop.util.NativeCodeLoader <clinit>
WARNING: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Mar 16, 2014 4:00:40 PM org.apache.hadoop.io.compress.snappy.LoadSnappy <clinit>
WARNING: Snappy native library not loaded
Mar 16, 2014 4:00:40 PM org.apache.hadoop.mapred.JobClient monitorAndPrintJob
INFO: Running job: job_201403151655_0012
Mar 16, 2014 4:00:41 PM org.apache.hadoop.mapred.JobClient monitorAndPrintJob
INFO:  map 0% reduce 0%
Mar 16, 2014 4:00:57 PM org.apache.hadoop.mapred.JobClient monitorAndPrintJob
INFO: Task Id : attempt_201403151655_0012_m_000000_0, Status : FAILED
java.lang.RuntimeException: java.lang.ClassNotFoundException: org.conan.myhadoop.mr.WordCount$WordCountMapper
	at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:857)
	at org.apache.hadoop.mapreduce.JobContext.getMapperClass(JobContext.java:199)
	at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:718)
	at org.apache.hadoop.mapred.MapTask.run(MapTask.java:364)
	at org.apache.hadoop.mapred.Child$4.run(Child.java:255)
	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:1190)
	at org.apache.hadoop.mapred.Child.main(Child.java:249)

解决方案:

我把这个WorldCount程序打成jar包在ubuntu上是可以正常运行,但如果继续在windows下运行程序的话需要按照下面的步骤:
  1、网上好多说要设置这job.setJarByClass(WordCount.class);但是hadoop-1.1.2的worldcount源码是有job.setJarByClass(WordCount.class);我们找到conf所在的位置,加conf.set("mapred.jar", "C:/Users/admin/Documents/DigDig/Hadoop/myHadoop/myHadoop.jar");  注意:"mapred.jar"不能改,后面是你导出jar的路径
  2、把工程打成xx.jar就是上面的mapreduce.jar,(右击工程->选择Export->选择要输出的package),我放在"C:/Users/exinglo/Documents/DigDig/Hadoop/myHadoop/",一般最好放工程里面,默认路径下
最后运行就可以了,然后就可以正常运行了,哈哈....虽然还是有点麻烦,要打jar包还要每次设置conf.set(),但是至少目前不用换环境了,比起每次上传到ubuntu再运行方便了一点点,对于初学的我来说已经是很好的开始,我觉得自己肯定是哪还没有配置好,应该还可以继续改进,继续研究...希望有知道的大神留下宝贵的意见!!

这里的方法参考了http://www.th7.cn/Program/java/201312/166507.shtml


原因分析:

http://blog.youkuaiyun.com/zklth/article/details/5816435

上面这篇文章提到了一些可能原因,但是下面有人质疑JobTracer的作用,暂时先放在这里,等后面详细学习内部机制。

<think>好的,用户遇到了Tez执行任务时出现的ClassNotFoundException,具体是找不到org.apache.hadoop.log.metrics.EventCounter这个类。我需要根据提供的引用信息来找出解决方案。 首先,看引用[4]和[5],里面提到log4j的配置问题,无法实例化EventCounter类。用户可能缺少相关的JAR包或者配置错误。引用[4]提到即使去掉hive-log4j.properties会报错,但不影响使用,但这里用户的问题可能更严重,导致任务无法执行。 然后,引用[5]中的链接可能提供了线索,但需要访问那个链接。不过根据已有的信息,可能的解决方案是检查Hadoop和Tez的依赖包是否包含EventCounter类。如果Hadoop版本升级了,可能某些类被移动或删除了,导致兼容性问题。 另外,引用[3]提到Hive启动失败是因为缺少JDBC驱动,类似的问题可能是缺少Hadoop的某些JAR包。用户可能需要将包含EventCounter类的JAR包添加到Tez的类路径中。例如,检查hadoop-common的JAR是否在Tez的lib目录下。 可能的解决步骤包括:确认Hadoop相关JAR的存在,检查类路径配置,更新Tez或Hadoop的版本以解决兼容性问题,或者手动添加缺失的JAR文件。同时,查看日志文件中的详细错误信息,确认具体的缺失类和路径问题。</think>针对Tez执行任务时出现的$ClassNotFoundException: org.apache.hadoop.log.metrics.EventCounter$异常,以下是分步解决方案: **1. 检查Hadoop依赖完整性** - 确认所有Hadoop基础组件(特别是$hadoop-common-x.x.x.jar$)已正确部署在Tez的lib目录下 - 验证Hadoop与Tez的版本兼容性,建议使用官方推荐的组合如: $$Hadoop\ 3.x + Tez\ 0.10.x$$ 版本不匹配是常见的类加载失败原因[^3] **2. 配置类路径扩展** - 在$tez-site.xml$中添加全局类路径配置: ```xml <property> <name>tez.cluster.additional.classpath.prefix</name> <value>/usr/hdp/current/hadoop-client/*</value> </property> ``` - 更新$HIVE_HOME/conf/hive-env.sh$: ```bash export TEZ_JARS="/usr/hdp/current/tez-client/*:/usr/hdp/current/tez-client/lib/*" export HIVE_AUX_JARS_PATH=$TEZ_JARS ``` **3. 日志配置修正** - 检查$hive-log4j.properties$中是否存在冲突的Appender配置 - 尝试注释或删除与EventCounter相关的配置项[^4][^5] **4. 依赖包手动修复** ```bash # 查找缺失类所在的JAR包 find /usr/hdp/ -name "hadoop-common*.jar" -exec grep -l "EventCounter" {} \; # 确认结果后复制到Tez的lib目录 sudo cp hadoop-common-3.3.1.3.0.1.0-187.jar /usr/hdp/current/tez-client/lib/ ``` **5. 验证配置** ```bash hive --service tez --check # 正常应输出TezSessionPool相关信息 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值