Going my way

いいなと思ったことをメモしていきます。

Javaの実行コマンドとクラスパスの指定、jarにパスを通して実行する方法など


Advertisements


Javaアプリケーションの実行

外部jarの参照など、eclipseで設定するのは簡単だ。
しかし、linuxバッチ処理として動かしたいときなどはjavaコマンドを使い、
その際は-classpathの設定をしなければならない。

Javaアプリケーションの実行の際は、依存関係のあるすべてのクラスは実行環境(JVM)から検索可能でなければならないからだ。

先日作成したTweetTestのソースを実行してみる。
これを実行するにはtwitter4Jにクラスパスが通っている必要がある。

■javacコマンド
javacコマンドはjavaプログラムのソースをコンパイルするためのコマンドである。

以下のようなオプションがある。
[-d]
クラスファイルを出力するディレクトリを指定する。
デフォルトではカレントディレクトリに出力される。

[-classpath][-cp]
コンパイル時に参照されるクラスファイルを見つけるために使う。
デフォルトはカレントディレクトリ(.)

では、例を見てみよう。

C:\temp\twitter4j
というプロジェクトを用意した。

C:\temp>dir
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 9061-B91A です

 C:\temp のディレクトリ

2012/08/07  08:25    <DIR>          .
2012/08/07  08:25    <DIR>          ..
2012/05/21  22:32    <DIR>          app
2012/07/14  18:11    <DIR>          java
2012/08/07  08:25    <DIR>          twitter4j
               0 個のファイル                   0 バイト
               5 個のディレクトリ  140,101,054,464 バイトの空き領域

ここにある
C:\temp\twitter4j\src\test\TweetTest.java

コンパイルして
C:\temp\twitter4j\classes
以下にクラスファイルを出力したい。

【誤】クラスパスを通さない場合

C:\temp>javac -d twitter4j/classes twitter4j/src/test/TweetTest.java
twitter4j\src\test\TweetTest.java:3: パッケージ twitter4j は存在しません。
import twitter4j.Twitter;

上記のようなエラーが出る

コンパイル時に
C:\temp\twitter4j\lib\twitter4j-core-2.2.6.jar
を参照するようにオプションで指定してみよう。

この場合のコマンドは以下の通り(カレントディレクトリはC:\temp)

C:\temp>javac -classpath twitter4j/lib/twitter4j-core-2.2.6.jar -d twitter4j/classes twitter4j/src/test/TweetTest.java

C:\temp\twitter4j\classes\test以下に
TweetTest.class
が作成された。


javaコマンド
javaコマンドで指定するクラスは必ず、メインメソッドを持つクラスでなければならない。

C:\tempディレクトリから、先ほど作成したclassファイルを実行してみる。

C:\temp>java twitter4j.classes.test.TweetTest

すると、以下のエラーが出る。

Exception in thread "main" java.lang.NoClassDefFoundError: twitter4j/classes/tes
t/TweetTest (wrong name: test/TweetTest)

なぜかというと、必要なクラスパスが通っていないからだ、

では、C:\temp\twitter4j\lib\twitter4j-core-2.2.6.jarにクラスパスを通して実行してみる。

C:\Users\temp>java -classpath C:\temp\twitter4j\classes;C:\temp\twitter4j\
lib\twitter4j-core-2.2.6.jar test.TweetTest
ツイートしたよw

うまく実行できたようだ。

ここで注意すべき点がいくつかある
① -classpathは上書きされる

  • classpathを指定すると、デフォルトが.(カレントディレクトリ)なのが上書きされる。

なので、クラスファイルを見つけるためのパスも通さなければならない。

windowsは「;(セミコロン)」で区切り、linuxは「:(コロン)」で区切る。
環境変数を設定するときもwindowsは「;」で区切るよね。それと同じ。

②パッケージからFQDN
Javaファイルの先頭が

package test;

のようになっているときは、-classpath をtestを格納しているフォルダに通そう。
そして、java test.TweetTest
というように、.(ドット)で区切って実行するんだ。
そうしないと、パッケージ構成のところでエラーが出る。

■自動的に検索されるクラス
\Java\jre1.6.0_31\lib\ext
のように、%JAVA_HOME%/jre/lib/ext以下は「拡張ディレクトリと呼ばれ、
ここに置いたJARファイルやクラスファイルは自動的にCLASSPATHに追加される。