久しぶりにMapReduceじゃなくてタダのJavaを書いたらハマった話
Apache HiveのオフィシャルWikiのサンプルをコピペして,JDBC経由でJavaからリモートのhive serverにアクセスしようと思ったわけですよ.
HiveClient - Apache Hive - Apache Software Foundation
まず準備部分だけ.こんな感じでイケるはず.
public class HiveClientDriver { private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver"; public static void main(String[] args) { System.out.println("classpath=" + System.getProperty("java.class.path")); try { Class.forName(driverName); } catch (ClassNotFoundException e) { e.printStackTrace(); System.exit(1); } System.out.println("END"); } }
しかし既にハマる.
コンパイルして実行.
% javac HiveClientDriver.java % java HiveClientDriver classpath=. java.lang.ClassNotFoundException: org.apache.hadoop.hive.jdbc.HiveDriver 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:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:190) at HiveClientDriver.main(HiveClientDriver.java:6)
そりゃそーですよねーHiveのライブラリにクラスパスが通ってませんよねー.
オプションで指定する.
% java -cp .:/usr/local/hive/lib/hive-jdbc-0.10.0-cdh4.4.0.jar HiveClientDriver classpath=.:/usr/local/hive/lib/hive-jdbc-0.10.0-cdh4.4.0.jar END
OK.次にjarにしてやってみる.
まず,jarに詰めると同時にマニフェストにmain関数があるクラスを登録.
% jar cvfe HiveClientDriver.jar HiveClientDriver HiveClientDriver.class マニフェストが追加されました HiveClientDriver.classを追加中です(入=1110)(出=646)(41%収縮されました)
最初に作ったコンパイル後のクラスファイルが悪さするといけないので消す.
% rm -v HiveClientDriver.class HiveClientDriver.class
そしてクラスパスの指定を敢えてしないでエラーを確認しながら実行.
% java HiveClientDriver エラー: メイン・クラスHiveClientDriverが見つからなかったかロードできませんでした % java -cp . HiveClientDriver エラー: メイン・クラスHiveClientDriverが見つからなかったかロードできませんでした % java -jar HiveClientDriver.jar HiveClientDriver classpath=HiveClientDriver.jar java.lang.ClassNotFoundException: org.apache.hadoop.hive.jdbc.HiveDriver 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:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:190) at HiveClientDriver.main(HiveClientDriver.java:6) % java -cp /usr/local/hive/lib/hive-jdbc-0.10.0-cdh4.4.0.jar -jar HiveClientDriver.jar HiveClientDriver classpath=HiveClientDriver.jar java.lang.ClassNotFoundException: org.apache.hadoop.hive.jdbc.HiveDriver 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:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:190) at HiveClientDriver.main(HiveClientDriver.java:6)
ここで一瞬ハマる.
クラスパスの指定とjarの指定のオプションを同時に指定してしまって,-cpの指定は無視されていることがclasspath=の表示から分かります.
2006-09-08
クラスパス指定だけにして,やっと成功.
% java -cp /usr/local/hive/lib/hive-jdbc-0.10.0-cdh4.4.0.jar:HiveClientDriver.jar HiveClientDriver classpath=/usr/local/hive/lib/hive-jdbc-0.10.0-cdh4.4.0.jar:HiveClientDriver.jar END
このあと,Rubyでクラスパスの探索やjavaを実行するスクリプトを書いたのですが,ちょっとハマりました.
オフィシャルWikiに
と書いてあったので,適当に似たファイル名を探してcoreって入ってりゃいいだろーと思って
hadoop_core = "#{hadoop_home}/share/hadoop/mapreduce/hadoop-mapreduce-client-core-2.0.0-cdh4.5.0.jar"
とやると,
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/io/Writable at org.apache.hadoop.hive.jdbc.HiveStatement.executeQuery(HiveStatement.java:198) at org.apache.hadoop.hive.jdbc.HiveStatement.execute(HiveStatement.java:132)
と基本的なクラスが無いと言われました.正解はこっち.
hadoop_core = "#{hadoop_home}/share/hadoop/common/hadoop-common-2.0.0-cdh4.5.0.jar"