[exceptions]运行mapreduce 报mapper类(内部静态类) java.lang.ClassNotFoundException

问题

运行mapreduce 报mapper类(内部静态类) java.lang.ClassNotFoundException
代码中用job.setJarByClass(ExampleJob.class); 来设置主类的,没设置引用其他jar包

原因

这样设置相当于只给mapreduce任务设置了一个要加载的类,要用的mapper类没加载。

解决

第一步

如果像我这样mapper类写成静态内部类,可以在打包的时候把内部类也一起打包进jar

$ javac -cp $(hbase classpath) MapReduceMainClass.java
$ jar cf MapReduceMainClass.jar MapReduceMainClass*.class

其中,$(hbase classpath)会返回HBase类路径,*.class匹配HBaseDeleteMapReduce类及其内部静态类HBaseDeleteMapper的所有编译后的类文件。
jar cf命令用于创建一个JAR文件。JAR文件是Java中的一种归档文件格式,可以用于存储Java类、资源文件、库文件以及其他类型的文件。

jar cf命令的语法如下:

jar cf <jar-file> <file1> <file2> ...

其中,是要创建的JAR文件的名称,、等参数是要添加到JAR文件中的文件或目录的名称。如果指定的是目录,则该目录中的所有文件和子目录都将被添加到JAR文件中。

第二步

在执行MapReduce作业之前,你需要将HBaseDeleteMapReduce.jar文件添加到Hadoop类路径中,可以使用下面的命令:

$ export HADOOP_CLASSPATH=/path/to/MapReduceMainClass.jar

再使用hadoop jar命令来启动MapReduce作业:

$ hadoop jar MapReduceMainClass.jar 

mr任务依赖多个jar包

在使用Hadoop运行MapReduce作业时,如果你的作业依赖于多个JAR文件,你需要确保这些JAR文件都在作业的类路径中。有几种方式可以实现这一点:

方式1

将所有的依赖JAR文件打包成一个JAR文件。这是最常见的方式,你可以使用jar cf命令将所有依赖的JAR文件打包成一个大JAR文件,并将该JAR文件添加到作业的类路径中。

$ jar cf mylib.jar /path/to/dependency1.jar /path/to/dependency2.jar ...

在提交作业时,将该JAR文件添加到类路径中:

$ hadoop jar myjob.jar -libjars /path/to/mylib.jar <input> <output>

注意,你需要将JAR文件的路径传递给-libjars选项,该选项接受一个以逗号分隔的JAR文件列表。

方式2

  1. 将依赖JAR文件添加到Hadoop类路径中。你可以将依赖的JAR文件拷贝到Hadoop类路径中(例如,$HADOOP_HOME/lib目录),这样它们就会被自动加载。(这个我理解应该是每个运行mr任务的机器上吧)

方式3

  1. 使用-classpath选项指定类路径。你可以使用-classpath选项将所有依赖JAR文件的路径以逗号分隔的形式传递给作业提交命令:
$ hadoop jar myjob.jar -classpath /path/to/dependency1.jar:/path/to/dependency2.jar <input> <output>

注意,你需要使用冒号分隔不同的路径。

总之,在设置作业的类路径时,你需要确保所有依赖的JAR文件都在该路径中。

补充:-libjars VS -classpath

-libjars-classpath 都是用来指定依赖的jar包的参数,但它们在用法和作用上有一些区别。

-libjars 是用来指定任务运行所需的jar包的位置,它将在运行时将这些jar包分发到所有的Task节点上,使得Task节点可以加载这些jar包中的类和资源。使用该参数时,可以指定多个jar包,它们之间使用逗号分隔。

-classpath 是用来指定运行任务所需的类路径的参数。类路径指的是JVM用来搜索类和资源的路径,通常是包含一些jar包和目录的路径。使用该参数时,可以指定多个目录和jar包,它们之间使用分号(Windows)或冒号(Unix/Linux)分隔。

总的来说,-libjars 主要用于指定任务运行所需的jar包,而 -classpath 主要用于指定任务运行时需要的类路径,包括一些自定义的类或第三方依赖的jar包。两者通常一起使用, -libjars 用于指定所有需要的jar包, -classpath 则用于指定自定义类和其他额外的jar包。

如果任务代码中使用了第三方依赖的jar包,而这些依赖的jar包不在Task节点上,则会抛出ClassNotFoundExceptionNoClassDefFoundError等类加载异常。为了避免这种情况,可以通过-libjars参数指定所有需要的jar包,它们将被分发到所有的Task节点上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值