使用 java.lang.NoClassDefFoundError 在 AWS EMR 上运行 Pig UDF:org/apache/pig/LoadFunc

Posted

技术标签:

【中文标题】使用 java.lang.NoClassDefFoundError 在 AWS EMR 上运行 Pig UDF:org/apache/pig/LoadFunc【英文标题】:Pig UDF running on AWS EMR with java.lang.NoClassDefFoundError: org/apache/pig/LoadFunc 【发布时间】:2012-12-05 01:13:13 【问题描述】:

我正在开发一个应用程序,它尝试读取存储在 S3 bucks 中的日志文件并使用 Elastic MapReduce 对其进行解析。当前日志文件具有以下格式

------------------------------- 
COLOR=Black 
Date=1349719200 
PID=23898 
Program=Java 
EOE 
------------------------------- 
COLOR=White 
Date=1349719234 
PID=23828 
Program=Python 
EOE 

所以我尝试将文件加载到我的 Pig 脚本中,但内置的 Pig Loader 似乎无法加载我的数据,所以我必须创建自己的 UDF。由于我对 Pig 和 Hadoop 还很陌生,因此我想在编写自己的脚本之前先尝试其他人编写的脚本,以了解 UDF 的工作原理。我从这里找到了一个http://pig.apache.org/docs/r0.10.0/udf.html,有一个 SimpleTextLoader。为了编译这个 SimpleTextLoader,我必须添加一些导入,如

import java.io.IOException; 
import java.util.ArrayList;
import org.apache.hadoop.io.Text; 
import org.apache.hadoop.mapreduce.Job; 
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat; 
import org.apache.hadoop.mapreduce.InputFormat; 
import org.apache.hadoop.mapreduce.RecordReader; 
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; 
import org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigSplit; 
import org.apache.pig.backend.executionengine.ExecException; 
import org.apache.pig.data.Tuple; 
import org.apache.pig.data.TupleFactory;
import org.apache.pig.data.DataByteArray; 
import org.apache.pig.PigException; 
import org.apache.pig.LoadFunc;

然后,我发现我需要编译这个文件。我要下载svn和pig running

sudo apt-get install subversion 
svn co http://svn.apache.org/repos/asf/pig/trunk 
ant

现在我有一个 pig.jar 文件,然后我尝试编译这个文件。

javac -cp ./trunk/pig.jar SimpleTextLoader.java 
jar -cf SimpleTextLoader.jar SimpleTextLoader.class 

它编译成功,我在 Pig 中输入 grunt,在 grunt 中我尝试加载文件,使用

grunt> register file:/home/hadoop/myudfs.jar
grunt> raw = LOAD 's3://mys3bucket/samplelogs/applog.log' USING myudfs.SimpleTextLoader('=') AS (key:chararray, value:chararray); 

2012-12-05 00:08:26,737 [main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 2998: Unhandled internal error. org/apache/pig/LoadFunc Details at logfile: /home/hadoop/pig_1354666051892.log

在pig_1354666051892.log里面,有

Pig Stack Trace
---------------
ERROR 2998: Unhandled internal error. org/apache/pig/LoadFunc

java.lang.NoClassDefFoundError: org/apache/pig/LoadFunc

我还尝试使用来自http://wiki.apache.org/pig/UDFManual 的另一个 UDF (UPPER.java),但尝试使用 UPPER 方法仍然会遇到相同的错误。你能帮帮我吗,这里有什么问题吗?非常感谢!

更新:我确实在 /home/hadoop/lib/pig/pig.jar 尝试了 EMR 内置 Pig.jar,但遇到了同样的问题。

【问题讨论】:

为什么不使用 EMR 中内置的 Pig 支持? 是的,我确实在 /home/hadoop/lib/pig/pig.jar 中使用了内置 pig,但仍然遇到相同的错误。我还在我的脚本中专门注册了这个 pig.jar 文件。但仍然得到同样的错误。 您可以简单地将您在本地开发的 Pig 脚本提供给 EMR,方法是将其放在 S3 中。 AWS 会为您处理所有配置和引导。 我在交互模式下运行。 EMR 更适合大规模运行。我建议您在您的机器上以本地模式开发您的脚本,并且只将最终脚本部署到 EMR。无论如何,请注意,您可以在 EMR 集群中拥有多个版本的 Hadoop。也许您没有选择您想要的正确版本。 【参考方案1】:

把UDF jar放到/home/hadoop/lib/pig目录下或者把pig-*-amzn.jar文件复制到/home/hadoop/lib下就可以了。

您可能会使用引导操作来执行这些操作。

【讨论】:

【参考方案2】:

大多数 Hadoop 生态系统工具(例如 pig 和 hive)都在 $HADOOP_HOME/conf/hadoop-env.sh 中查找环境变量。

我能够通过将 pig-0.13.0-h1.jar(它包含 UDF 所需的所有类)添加到 HADOOP_CLASSPATH 来解决此问题:

export HADOOP_CLASSPATH=/home/hadoop/pig-0.13.0/pig-0.13.0-h1.jar:$HADOOP_CLASSPATH

pig-0.13.0-h1.jar 在 Pig 主目录中可用。

【讨论】:

以上是关于使用 java.lang.NoClassDefFoundError 在 AWS EMR 上运行 Pig UDF:org/apache/pig/LoadFunc的主要内容,如果未能解决你的问题,请参考以下文章

Log4j2/Slf4j 和 Java 11

windows10下使用spark-2.3.0-bin-without-hadoop相关问题

测试使用

第一篇 用于测试使用

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇