2013年9月6日金曜日

【Java】cannot be resolved to a type エラーと CLASSPATH の順序

Java の クラスパス の設定でちょっと躓いたので記録。

javac や java コマンドの実行時にクラスパスを指定するには2通りのやり方がある。 -classpath オプションを使う方法と CLASSPATH 環境変数を使う方法だ。今回検証したのは環境変数による設定のみである。

発生した問題を説明する。依存ライブラリの jar ファイルを全て CLASSPATH に含めて java コマンドを実行しても、コンパイルした bin ディレクトリ外では以下の様なエラーが発生した。

Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
 Options cannot be resolved to a type
 Options cannot be resolved to a type
 CommandLineParser cannot be resolved to a type
 PosixParser cannot be resolved to a type
 CommandLine cannot be resolved to a type
 Option cannot be resolved to a type
 ParseException cannot be resolved to a type

 at com.github.uchan_nos.c_helper.Launcher.main(Launcher.java:32)

コンパイル時はエラーがなく、さらに bin ディレクトリで java コマンドを実行すれば正常に実行されるのに、 java コマンドを実行するときのカレントディレクトリが異なるとダメになる。

この時のクラスパスの設定は次。
export CLASSPATH=`python ~/gitrepos/c-helper/tools/classpath.py /Applications/eclipse/plugins`:~/java/lib/commons-cli-1.2/commons-cli-1.2.jar:~/gitrepos/c-helper/bin

`と`で囲まれた python コマンドは、依存している jar ファイルの名前をコロン区切りにするためのもの。その後ろに追加で依存する commons-cli-1.2.jar ファイルを指定した。

このようなときは、クラスパスの順序を変えれば解決するかもしれない。今回の場合は以下のように修正したら解決した。
export CLASSPATH=~/java/lib/commons-cli-1.2/commons-cli-1.2.jar:~/gitrepos/c-helper/bin:`python ~/gitrepos/c-helper/tools/classpath.py /Applications/eclipse/plugins`

私自身クラスパスの仕組みをはっきりと把握できていないため、今回の対処法が全ての場合で有効かは分からないが、今回の場合はこれが特効薬だった。