1. 程式人生 > >hadoop 中的 ClassNotFoundException

hadoop 中的 ClassNotFoundException

2012-06-11

在執行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下的類。解決辦法:

  1. 將hbase下的配置檔案hbase-site.xml拷貝到hadoop的conf目錄下,將hbase下的lib檔案,拷貝到hadoop下的lib檔案。並將變動應用到叢集的每一臺機器。

  2. 編輯$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

如非註明轉載, 均為原創. 本站遵循

知識共享CC協議,轉載請註明來源