在通过Hadoop-2.6.0的C的API访问HDFS的时候,编译和运行出现了不少问题,花费了几天的时间,上网查了好多的资料,终于还是把问题给解决了
参考文献:
系统:CentOS 6.6,hadoop-2.6.0, 在hadoop集群的datanode机器上进行
样例代码来源官方文档中的CAPI libhdfs:
#include"hdfs.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char **argv) {
hdfsFS fs =hdfsConnect("10.25.100.130", 9000);//在这里做了一点修改
const char* writePath ="/tmp/testfile.txt";
hdfsFile writeFile = hdfsOpenFile(fs,writePath, O_WRONLY|O_CREAT, 0, 0, 0);
if(!writeFile) {
fprintf(stderr, "Failed toopen %s for writing!\n", writePath);
exit(-1);
}
char* buffer = "Hello,World!";
tSize num_written_bytes = hdfsWrite(fs,writeFile, (void*)buffer, strlen(buffer)+1);
if (hdfsFlush(fs, writeFile)) {
fprintf(stderr, "Failed to’flush’ %s\n", writePath);
exit(-1);
}
hdfsCloseFile(fs, writeFile);
}
接下来就是编译,,按照官网上给出的:
How To Link With The Library
See the CMake filefortest_libhdfs_ops.cin the libhdfssource directory (hadoop-hdfs-project/hadoop-hdfs/src/CMakeLists.txt) or something like:gcc above_sample.c -I$HADOOP_HDFS_HOME/include -L$HADOOP_HDFS_HOME/lib/native-lhdfs -o above_sample
试用第二种:
[root@node04 ~]# gcc above_sample.c -I/home/hadoop/hadoop-2.6.0/include/ -L /home/hadoop/hadoop-2.6.0/lib/native/-lhdfs -o above_sample
可以通过,查了好多资料,很少有人使用这一种,如何使用这一种有错误,也可以换用另外一种。
我使用的是这一种编译方式:
[root@node04 ~]# gcc above_sample.c -I/home/hadoop/hadoop-2.6.0/include/ -L /home/hadoop/hadoop-2.6.0/lib/native/-lhdfs /usr/java/jdk1.7.0_75/jre/lib/amd64/server/libjvm.so -o above_sample
这两种方法都可以生成一个可执行的文件above_sample
编译通过,可以在运行的时候出现以下错误:
[root@node04 ~]# ./above_sample
./above_sample: error while loading sharedlibraries: libjvm.so: cannot open shared object file: No such file or directory
首先要找到缺失这个库的存在路径
[root@node04 ~]# find / -name libhdfs.so.0.0.0
/home/hadoop/hadoop-2.6.0/lib/native/libhdfs.so.0.0.0
[root@node04 ~]# find / -name libjvm.so
/usr/java/jdk1.7.0_75/jre/lib/amd64/server/libjvm.so
[root@node04 ~]# vi /etc/ld.so.conf
编辑后如下:
include ld.so.conf.d/*.conf
/home/hadoop/hadoop-2.6.0/lib/native/
/usr/java/jdk1.7.0_75/jre/lib/amd64/server/
分别添加了两个路径,每个路径占一行。编辑完后,重新加载库:
[root@node04 ~]# /sbin/ldconfig –v
这一种方法是是针对整个系统,启动时就加载。
然后我们就继续执行可执行文件:
[root@node04 ~]# ./above_sample
loadFileSystemserror:
(unabletogetstacktraceforjava.lang.NoClassDefFoundErrorexception:ExceptionUtils::getStackTraceerror.)
hdfsBuilderConnect(forceNewInstance=0,nn=172.25.40.171,port=9001,kerbTicketCachePath=(NULL),userName=(NULL))error:
(unabletogetstacktraceforjava.lang.NoClassDefFoundErrorexception:ExceptionUtils::getStackTraceerror.)
经过查找资料发现:
上述信息中的关键项是“NoClassDefFoundError”和“ExceptionUtils”,也就是找不到ExceptionUtils,一般可推断是因为找不到相应的jar文件,Google搜索“ExceptionUtilsjar”,发现“ExceptionUtils”应当是在包apache-commons-lang.jar中。
进一步用Google去搜索“apache-commons-lang.jar”,找到下载网址:,上面可以下载commons-lang3-3.3.2-bin.tar.gz,解压后就可以看到commons-lang3-3.3.2.jar。
hadoop的二进制安装包,应当自带了这个文件,通过努力,在hadoop安装目录下的share/hadoop/tools/lib子目录下发现了commons-lang-2.6.jar,应当就是它了
然后修改我们的环境变量,在我们配置java环境变量之后添加hadoop的环境变量
[root@node04 ~]# vi /etc/profile
unset i
unset -f pathmunge
export JAVA_HOME=/usr/java/jdk1.7.0_75
export JRE_HOME=$JAVA_HOME/jre
exportCLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib/rt.jar:/usr/share/gtksourceview-2.0/language-specs/java.lang
PATH=$PATH:$JAVA_HOME/bin
HADOOP_HOME=/home/hadoop/hadoop-2.6.0
exportPATH=$HADOOP_HOME/bin:$PATH
exportCLASSPATH=.:$HADOOP_HOME/share/hadoop/common/lib/commons-lang-2.6.jar
loadFileSystemserror:
java.lang.NoClassDefFoundError:org/apache/hadoop/fs/FileSystem
Causedby:java.lang.ClassNotFoundException:org.apache.hadoop.fs.FileSystem
atjava.net.URLClassLoader$1.run(URLClassLoader.java:372)
atjava.net.URLClassLoader$1.run(URLClassLoader.java:361)
atjava.security.AccessController.doPrivileged(NativeMethod)
atjava.net.URLClassLoader.findClass(URLClassLoader.java:360)
atjava.lang.ClassLoader.loadClass(ClassLoader.java:424)
atsun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
atjava.lang.ClassLoader.loadClass(ClassLoader.java:357)
hdfsBuilderConnect(forceNewInstance=0,nn=10.25.100.130,port=9000,kerbTicketCachePath=(NULL),userName=(NULL))error:
java.lang.NoClassDefFoundError:org/apache/hadoop/conf/Configuration
Causedby:java.lang.ClassNotFoundException:org.apache.hadoop.conf.Configuration
atjava.net.URLClassLoader$1.run(URLClassLoader.java:372)
atjava.net.URLClassLoader$1.run(URLClassLoader.java:361)
atjava.security.AccessController.doPrivileged(NativeMethod)
atjava.net.URLClassLoader.findClass(URLClassLoader.java:360)
atjava.lang.ClassLoader.loadClass(ClassLoader.java:424)
atsun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
atjava.lang.ClassLoader.loadClass(ClassLoader.java:357)
[root@node04~]# vi /etc/profile
也有善意的提醒:何不去远方!昆明呀——赶一个花海;