运行hadoop jar 报错java.lang.RuntimeException: java.lang.ClassNotFoundException: xxxxMapper及mapreduce执行

本文探讨了在Hadoop1.0.2版本中执行jar包时出现的ClassNotFoundException问题及解决方案,分析了hadoop jar命令的具体执行流程,并提出了几种有效的解决方法。

最近做hadoop集群试验,用的hadoop1.0.2,遇到这么个问题,将写好的jar包,放到linux上后,执行hadoop jar hadoopTest.jar test.XXXCount  input output 后,

运行时,会报下面的警告

WARN mapred.JobClient: No job jar file set. 

User classes may not be found. See JobConf(Class)or JobConf#setJar(String).
之后就会报错:
java.lang.RuntimeException: java.lang.ClassNotFoundException: xxxxMapper
虽然从网上查了很多,基本都是写需要在声明job时,加上 job.setJarByClass(WordCount.class);
但是我加上之后还是运行不对,之后看源码后才发现,有一个判断,是判断"jar".equals(url.getProtocol())但是,这个永远是在我debug后得知,url.getProtocol()永远是“file”,不是“jar”,原因我想可能是hadoop jar的流程(详见下面转的hadoop jar流程)中,这条命令,会将jar解压到/home/hadoop/hadoop-fs/dfs/temp/hadoop- unjarxxxxxx这样的目录下,所以程序执行时,通过class名称,根本找不到jar包。当然也可能是这个1.0.2的版本有bug,或者我使用的方法不对。

我现在的解决办法是在Configuration里加上配置,将需要用到的jar通过配置加进来: conf.set("mapred.jar", "/home/test/hadoopTest.jar");

还有几种方法,没有试,一个是在mapred-site.xml配置文件中加上property,另外一个就是在<<基于Hadoop实现通用的并行任务处理>>中提到项目依赖包可通过Hadoop的DistributedCache功能来保证分布运行。同样,我们也可以利用它将入口类所在的Jar包加入到DistributedCache中,同时避免设置mapred.jar选项(调用Job类的setJarByClass方法做到)。这样就少了两次copy的过程。

参考:【转】hadoop jar xxxx.jar的流程


搞清楚 hadoop jar xxxx.jar 执行的流程: jar文件是如何分发的

JobClient(不一定是hadoop集群的节点)利用bin/hadoop脚本运行jar包,以 hadoop-0.20.2-examples.jar为例子:
hadoop jar hadoop-0.20.2-examples.jar [class name]的实质是:
1.利用hadoop这个脚本 启动一个jvm进程;
2.jvm进程去 运行org.apache.hadoop.util.RunJar这个java类;
3.org.apache.hadoop.util.RunJar 解压hadoop-0.20.2-examples.jar 到hadoop.tmp.dir/hadoop-unjar*/目录下 ;
4.org.apache.hadoop.util.RunJar动态的 加载并运行Main-Class或指定的Class;
5.Main-Class或指定的Class中 设定Job的各项属性
6. 提交job到JobTracker上并监视运行情况。

注意:以上都是在jobClient上执行的。

运行jar文件的时候,jar会被解压到hadoop.tmp.dir/hadoop-unjar*/目录下(如:/home/hadoop/hadoop-fs/dfs/temp/hadoop- unjar693919842639653083, 注意:这个目录是JobClient的目录,不是JobTracker的目录)。解压后的文件为:
drwxr-xr-x 2 hadoop hadoop 4096 Jul 30 15:40 META-INF
drwxr-xr-x 3 hadoop hadoop 4096 Jul 30 15:40 org
有图有真相:


提交job的实质是:
生成${job-id}/job.xml文件到hdfs://${mapred.system.dir}
/(比如hdfs://bcn152:9990/home/hadoop/hadoop-fs/dfs/temp/mapred/system/job_201007301137_0012/job.xml),job的描述包括 jar文件的路径map|reduce类路径等等.
上传 ${job-id}/job.jar文件到hdfs://${mapred.system.dir}/(比如hdfs://bcn152:9990/home/hadoop/hadoop-fs/dfs/temp/mapred/system/job_201007301137_0012/job.jar)
有图有真相:


生成job之后,通过static JobClient.runJob()就会向jobTracker提交job:
JobClient jc = new JobClient(job);
RunningJob rj = jc.submitJob(job);
之后JobTracker就会调度此job,

提交job之后,使用下面的代码获取job的进度:
    try {
      if (!jc.monitorAndPrintJob(job, rj)) {
        throw new IOException("Job failed!");
      }
    } catch (InterruptedException ie) {
      Thread.currentThread().interrupt();
    }
0
[root@jt ~][root@jt ~]# hadoop jar /opt/state-total-1.0-jar-with-dependencies.jar StateTotalDriver \-libjars /opt/mysql 25/11/14 10:02:50 INFO client.RMProxy: Connecting to ResourceManager at jt/192.168.254.130:8032 25/11/14 10:02:53 WARN mapreduce.JobResourceUploader: Hadoop command-line option parsing not performed. Implement the Tool interface and execute your application with ToolRunner to remedy this. 25/11/14 10:02:55 INFO mapreduce.JobSubmitter: Cleaning up the staging area /tmp/hadoop-yarn/staging/root/.staging/job_1763084590187_0003 Exception in thread "main" java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver at org.apache.hadoop.mapreduce.lib.db.DBInputFormat.setConf(DBInputFormat.java:171) at org.apache.hadoop.util.ReflectionUtils.setConf(ReflectionUtils.java:76) at org.apache.hadoop.util.ReflectionUtils.newInstance(ReflectionUtils.java:136) at org.apache.hadoop.mapreduce.JobSubmitter.writeNewSplits(JobSubmitter.java:298) at org.apache.hadoop.mapreduce.JobSubmitter.writeSplits(JobSubmitter.java:318) at org.apache.hadoop.mapreduce.JobSubmitter.submitJobInternal(JobSubmitter.java:196) at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1290) at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1287) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:422) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1762) at org.apache.hadoop.mapreduce.Job.submit(Job.java:1287) at org.apache.hadoop.mapreduce.Job.waitForCompletion(Job.java:1308) at StateTotalDriver.main(StateTotalDriver.java:51) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.hadoop.util.RunJar.run(RunJar.java:226) at org.apache.hadoop.util.RunJar.main(RunJar.java:141) Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver at org.apache.hadoop.mapreduce.lib.db.DBInputFormat.createConnection(DBInputFormat.java:205) at org.apache.hadoop.mapreduce.lib.db.DBInputFormat.setConf(DBInputFormat.java:164) ... 19 more Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:264) at org.apache.hadoop.mapreduce.lib.db.DBConfiguration.getConnection(DBConfiguration.java:148) at org.apache.hadoop.mapreduce.lib.db.DBInputFormat.createConnection(DBInputFormat.java:198) ... 20 more
最新发布
11-15
Hadoop作业运行报错`java.lang.ClassNotFoundException: com.mysql.jdbc.Driver`时,意味着Java虚拟机在运行时无法找到`com.mysql.jdbc.Driver`,该是MySQL JDBC驱动的一部分。以下是一些可能的解决方案: ### 检查驱动是否存在 确保MySQL JDBC驱动(通常是`mysql-connector-java.jar`)已经存在于Hadoop集群的路径中。可以将该驱动添加到Hadoop的`lib`目录下,例如`$HADOOP_HOME/lib`。 ### 配置驱动路径 在相关配置文件中明确指定MySQL JDBC驱动的路径。以引用[4]中的配置文件`my.properties`为例,确保配置文件中正确指定了MySQL驱动: ```properties mysql.jdbc.driver=com.mysql.jdbc.Driver mysql.db.url=jdbc:mysql://node1:3306/real_result mysql.user=root mysql.password=123456 mysql.connection.pool.size=10 ``` ### 提交作业时指定驱动 在提交Hadoop作业时,可以通过`-libjars`参数指定MySQL JDBC驱动的路径。例如: ```bash hadoop jar your_job.jar your.main.Class -libjars /path/to/mysql-connector-java.jar ``` ### 检查版本兼容性 确保使用的MySQL JDBC驱动版本与MySQL服务器版本兼容。同时,也要注意驱动版本与Java版本的兼容性,如引用[3]中提到的`java.lang.UnsupportedClassVersionError`问题,可能是由于驱动版本与Java版本不兼容导致的。 ### 检查环境变量 确保`CLASSPATH`环境变量包含了MySQL JDBC驱动的路径。可以通过以下命令查看和设置`CLASSPATH`: ```bash echo $CLASSPATH export CLASSPATH=$CLASSPATH:/path/to/mysql-connector-java.jar ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值