hadoop 中的 ClassNotFoundException
在執行hbase或mapreduce的程式時,有時會遇到ClassNotFoundException。如果jar包裡的MANIFEST.MF沒有指定Main-Class,就會遇到這一問題。但如果指定無誤,還是會遇到這樣的問題。
有人的建議是將所有用到的jar包都打進要執行的jar包裡。這是一種解決方法。但即使將jar包全打進了新的jar檔案,還是會遇到該問題。如我在執行hbase的IndexBuilder這個例子時,遇到如下問題:
12/06/11 18:23:32 INFO mapred.JobClient: Task Id : attempt_201206111811_0001_m_000002_1, Status : FAILED java.lang.RuntimeException: java.lang.ClassNotFoundException: org.apache.hadoop.hbase.mapreduce.MultiTableOutputFormat at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:867) at org.apache.hadoop.mapreduce.JobContext.getOutputFormatClass(JobContext.java:235) at org.apache.hadoop.mapred.Task.initialize(Task.java:513) at org.apache.hadoop.mapred.MapTask.run(MapTask.java:353) at org.apache.hadoop.mapred.Child$4.run(Child.java:255) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:415) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1121) at org.apache.hadoop.mapred.Child.main(Child.java:249) Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.hbase.mapreduce.MultiTableOutputFormat at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:423) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:356) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:264) at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:820) at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:865) ... 8 more
中提到,MapReduce的Job部署到群集中,並不預設就能訪問hbase配置目錄和HBase下的類。解決辦法:
-
將hbase下的配置檔案hbase-site.xml拷貝到hadoop的conf目錄下,將hbase下的lib檔案,拷貝到hadoop下的lib檔案。並將變動應用到叢集的每一臺機器。
-
編輯$HADOOP_HOME/conf下的hadoop-env.sh檔案,將相關檔案和目錄加到
HADOOP_CLASSPATH中。但這有一個問題,就是會汙染hadoop的執行環境。如果不在意的話,倒是可以這麼用。但可能會有較大副作用。尤其是當環境出問題的時候。
HADOOP_CLASSPATH=${HBASE_HOME}/hbase-0.94.0.jar:
${HBASE_HOME}/bin/hbase classpath
注意將hbase-0.94.jar放在其他庫的前面。
3.在hbase 0.90版以後,可以只在本地環境修改CLASSPATH變數,不會對其他環境產生不良影響。
[[email protected] ~]$ HADOOP_CLASSPATH=${HBASE_HOME}/bin/hbase classpath
${HADOOP_HOME}/bin/hadoop jar multitb.jar cars.csv
如非註明轉載, 均為原創. 本站遵循