我有一个C++服务,它公开了2个接口:运行Hadoop作业时发生类加载问题
a。提交():用于向YARNRM提交DistCp作业
b。 Query():用于查询应用程序的状态。
此服务在内部调用Java客户端(通过JNI),其中有2个静态函数:
提交()
查询()
提交()做:
DistCp distCp = new DistCp(configuration, distCpOptions);
Job job = distCp.execute();
Parses the "application ID" from the tracking URL and returns it.
查询()的作用:
Takes "application ID" returned in Submit()
YarnClient yarnClient = YarnClient.createYarnClient();
yarnClient.init(new YarnConfiguration());
yarnClient.start();
yarnClient.getApplicationReport(applicationID);
yarnClient.stop();
我现在面临的问题是,
- 如果该服务的第一个电话被提交(),那么所有的后续调用(均提交()和查询())成功
- 但是,如果第一次调用服务是Query(),则所有Submit()调用FAIL。
Query()调用在所有条件下都成功。
的提交()调用失败,错误(第一个呼叫,第二个呼叫和下面第三个呼叫,用不同的例外):
java.util.ServiceConfigurationError: org.apache.hadoop.mapreduce.protocol.ClientProtocolProvider: Provider org.apache.hadoop.mapred.LocalClientProtocolProvider not found
java.util.ServiceConfigurationError: org.apache.hadoop.mapreduce.protocol.ClientProtocolProvider: Provider org.apache.hadoop.mapred.YarnClientProtocolProvider not found
java.io.IOException: Cannot initialize Cluster. Please check your configuration for mapreduce.framework.name and the correspond server addresses.
我调试了这个问题并发现,当首先调用Query()API时,则不会加载类LocalClientProtocolProvider
和YarnClientProtocolProvider
。当调用Submit()时,类加载器应该加载这些类。但是,这并没有发生。
我还观察到,当首先调用Query()API时,Hadoop配置发生变化,并且包含许多与“mapreduce。*”配置相关的默认设置。
一旦调用了Submit()方法,我尝试使用Class.forName()进行显式加载。但是,这也没有帮助。
当调用Submit()时,为什么类加载器不加载所需的类?这是Hadoop配置还是Java类加载器的问题?还是这是问题,因为我混合了MapReduce和Yarn API?
“mapreduce.framework.name”配置设置为“纱线”。
我的环境是Hadoop 2.6.0。
我的类路径中包含所有Hadoop的罐子存在于以下路径:
a. hadoop/common/
b. hadoop/common/lib
c. hadoop/hdfs/
d. hadoop/hdfs/lib
e. hadoop/mapreduce/
f. hadoop/mapreduce/lib
g. hadoop/yarn/
h. hadoop/yarn/lib