eclipse下执行wordcount报错 java.lang.ClassNotFoundException

我用 eclipse执行wordcout,报错如下,
网上一般都说是要加 job.setJarByClass( WordCount.class);,但我代码里有这句
另外,导出jar到 linux下就正常了
13/06/06 17:16:34 WARN mapred.JobClient: No job jar file set.  User classes may not be found. See JobConf(Class) or JobConf#setJar(String).
13/06/06 17:16:34 INFO input.FileInputFormat: Total input paths to process : 1
13/06/06 17:16:34 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
13/06/06 17:16:34 WARN snappy.LoadSnappy: Snappy native library not loaded
13/06/06 17:16:35 INFO mapred.JobClient: Running job: job_201306061707_0004
13/06/06 17:16:36 INFO mapred.JobClient:  map 0% reduce 0%
13/06/06 17:16:43 INFO mapred.JobClient: Task Id : attempt_201306061707_0004_m_000000_0, Status : FAILED
java.lang.RuntimeException: java.lang.ClassNotFoundException: WordCount$TokenizerMapper
        at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:849)
        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:255)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:416)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1149)

        at org.apache.hadoop.mapred.Child.main(Child.java:249)

初步解决:

网上通用方法根本行不通,看到一个网友如下解决方法:

首先还是 确保按照通用的方法:

在main添加

job.setJarByClass(WordCount.class); (一般版本都存在这个,下面会知道,这个是问题所在,其实无用)

然后如下:

自己解决了,
windows下先用eclipse导出jar到E:\\hadoop\\hadoop-1.1.2\\hadoop-1.1.2\\wordcount.jar,
代码里加句
conf.set("mapred.jar", "E:\\hadoop\\hadoop-1.1.2\\hadoop-1.1.2\\wordcount.jar");
就正常了,
不过如果想要到linux去执行,生成jar前要把这句删掉,
很是麻烦,哪位大神有更好的解决办法么
问题原因:

虽然这样解决了问题,但还是不理解,也觉得这种解决办法太勉强,找到以下文章,包括原因和解决方法,但是解决方法跟上面是一个道理,重点看原因即可

网上的说法大概有两种:

(1)“因为使用的是0.20以上的Hadoop版本,在调用jar中的自定义mapper时,需要设置setJarByClass方法,设置方法如下:job.setJarByClass(MyJob.class);” 这种说法见诸多出,比如:

http://bbs.hadoopor.com/thread-3926-1-1.html 

http://blog.csdn.net/jessezhang1981/article/details/7062096 

http://jessezhang1981.iteye.com/blog/1305515 

最抓瞎的是csdn的一个帖子,一哥们贴出了源码,明明其中有setJarByClass,但是下面的回帖还是说要setJarByClass。哎!

但一般的示例程序里面都会setJarByClass,而且从后面的实践中发现,清除我自己的愚蠢错误后,这种方法也是一点帮助也没有的。不知道是不是以为我现在的环境是伪分布式,而他们的环境不同。可能吧,天知道!

(2)“这个问题主要出在 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>

见下面的链接(还有其他的转载)

http://www.linuxidc.com/Linux/2012-02/54711.htm


自己理解


问题中的警告3/06/06 17:16:34 WARN mapred.JobClient: No job jar file set.  User classes may not be found. See JobConf(Class) or JobConf#setJar(String).

说明了job.setJarByClass(WordCoun.class)这个语句设置作业Jar包没有成功。这是为什么呢?

因为这个方法使用了WordCount.class的类加载器来寻找包含该类的Jar包,然后设置该Jar包为作业所用的Jar包。但是我们的作业 Jar包是在程序运行时才打包的,而WordCount.class的类加载器是AppClassLoader,运行后我们无法改变它的搜索路径,所以使用setJarByClass是无法设置作业Jar包的。我们必须使用JobConf里的setJar来直接设置作业Jar包,像下面一样:

  
  
((JobConf)job.getConfiguration()).setJar(jarFile);(此方法的jarFile变量不清楚应该是什么,主要是对setJar的功能不了解,这里不讨论这个方法,解决方法还是使用最初的)
所以原因就很清楚了,job.setJarByClass(WordCoun.class)这句话要设置jar包的路径,并让其作为作业jar包,但是程序运行的时候才会生成jar包,而此时不存在,所以失败。而我们最初的方法就是手动生成jar包,然后指定路径。所以这句话也不需要了。而linux下直接执行wordcount为什么可以呢?因为你执行的本来就是jar包,也就是说你用的代码本身就是打成jar包才能执行的,或者说job.setJarByClass(WordCoun.class)是在jar包环境执行的。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值