超不定期雑記

~プログラムとかサイエンスとかいろいろと~

目次

Blog 利用状況

ニュース

書庫

Java での開発の勉強をしてみる(4) コマンドラインからコンパイルと実行

インドリさんの助言に従い、今度はコマンドプロンプトからのコンパイルを試してみる。
これは、IDE の裏でコンパイラがどう動いているかを実感するのが目的。
C++ でもコンパイラやリンカの動きを想像してたらバグが見つかったなんてこともあったので、少なくとも芸の肥やしくらいにはなるだろう。

さてコマンドプロンプトからのコンパイル方法をぐぐってみたら、下記のページがヒットした。

Howdy, Java!

ふーん、なるほど。
コンパイラは javac で、ソースコードの拡張子は .java ね。
んじゃとりあえず、コマンドプロンプトで "javac" と叩いてみる。

'javac' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

えーと、えーと。"java" はそれなりの答えを返してくれたところをみると、インストールそのものはできていると思う。
ということは、自力で環境変数を設定しないといけない?
そう思ってぐぐったら、確かにその通りだった。

Step5・Java 環境変数のPathを設定

おーけーおーけー、んじゃ設定しよう。
やることはシステムのプロパティを使ってシステム環境変数 "Path" の最後に javac のディレクトリを追加するだけ。
ちなみに私の環境では、javac.exe は "C:\Program Files\Java\jdk1.6.0_12\bin" にある。
パスを通して再起動したら、ヘルプを返してくれた……って、日本語化されてる。これはありがたい。

んじゃ、先ほど作った Hello world! をテキストエディタで作り直してみる。

// Hello.java
public class HelloWorld
{
    public static void main( String[] args )
    {
        System.out.println( "Hello world!" );
    }
}

んでカレントディレクトリをソースコードディレクトリに移して、コマンドプロンプトから "javac hello.java" と叩いてみる。

hello.java:1: クラス HelloWorld は public であり、ファイル HelloWorld.java で宣
言しなければなりません。

……。Javaって、 public なクラスはクラス名と同じ名前のファイルで定義しないとダメなの?
そう思って先ほどのファイルを "HelloWorld.java" にリネームしてからコンパイルしたら、今度は正しくコンパイルされた。

ここでふと気がついた。
Java って、ネームスペースとフォルダ構成を一致させないといけないのか?
もしそれが保証されているとしたら、ゲートになるソースファイルを食わせるだけで、コンパイラはすべてのソースファイルを取得することができるはず。
ということは、プロジェクトファイルが必要なくなるんじゃないだろうか。
ちょっとおもしろそうなので上記については後で検証しておこう。
これが本当なら、いろいろと考察が広がりそうだし。

さてコンパイルした結果を見てみると、ソースファイルと同じディレクトリに .class ファイルができている。
これを java.exe に食わせれば、コマンドプロンプトに "Hello world!" と表示されるはず。
ということでコマンドプロンプトで "java HelloWorld" と叩いてみると、

Hello world!

と表示された。

※ CLASSPATH の設定をせずとも正常に動作しました。java.exe のオプションで、クラス名を小文字で指定したのがエラーの原因だったようです。
以下、恥さらし。

Exception in thread "main" java.lang.NoClassDefFoundError: helloworld (wrong nam
e: HelloWorld)
(中略)
Could not find the main class: helloworld. Program will exit.

あっるぇ~?
メインクラスが見つからないって、ちゃんと main メソッド書いたよ?
ぐぐったら同じような問題を抱えている人は多いようで、いくつもヒットした。
その中でも気になったのが、以下の投稿。

「Could not find the main class」の回避方法

環境変数 CLASSPATH ねぇ。
カレントディレクトリの .class ファイルを指定してるから、あんまり関係ないと思うけどなぁ。
そう思ってさらに検索してみると、下記で「カレントワーキングディレクトリ」なる単語を見つけた。

Java 環境のセットアップ

……。つまり、カレントディレクトリの .class ファイルを実行するにも CLASSPATH の指定が必要と?
上記ページの下の方に問題の切り分けに関する記述があって、そこにオプションでクラスパスを指定する方法が書かれていた。
ということで、試しに "java -classpath . HelloWorld" と打ってみる。

Hello world!

正解だったらしい。
この後 CLASSPATH に ".;" を定義して再起動したら、 "java HelloWorld" でも想定通りに動作した。
しかしデフォルトでカレントディレクトリを検索しないって、どういう意味があるんだろう?
何となく思想のようなものが透けて見える気がするけど、いまのところはよくわかんない。

以上のまとめとか雑感とか。

  • Java のソースファイルの拡張子は .java。
    • public なクラスは、同じファイル名のソースファイルで定義しなければならない?
  • Java のコンパイラは javac.exe。
    • コンパイルすると、 .class ファイルが生成される。これが Java の実行ファイル。
  • JDK をインストールしただけでは、コマンドラインツールを使用するのに不便。環境変数を設定すること。
    • PATH に javac.exe のパスを指定する。
    • CLASSPATH に ".;" を指定する。
      • 最後の ";" は必要ないと思うが、後のことを考えて付けておく。
  • java.exe にクラスを指定すると実行できる。
    • java.exe に食わせるのは「クラス」であって「.class ファイル」ではない。
      • 従って、Windows 環境であっても大文字小文字を厳密に区別する。
      • .class ファイルのフルパスを指定するのは無意味。そもそも、食わせるのはファイルではない。
    • 環境変数 CLASSPATH に "." が指定されていない場合、たとえカレントディレクトリに .class ファイルがあってもオプションなしでは実行できない。
      ※ ↑間違い。設定せずともカレントディレクトリの .class ファイルを実行することができます。
    • CLASSPATH に指定されていない場所の .class ファイルを実行するには、 -classpath オプションを利用する。-cp も同じ意味。
      • -classpath オプションはクラスの検索位置を指定するためのもの。従って "java -classpath .HelloWorld" なんてやると蹴られる。
        • ↑"." と "HelloWorld" の間にスペースがないのがエラーの原因。

投稿日時 : 2009年2月26日 11:17

Feedback

# re: Java での開発の勉強をしてみる(4) コマンドラインからコンパイルと実行 2009/02/26 12:47 凪瀬

CLASSPATH の.は不要のはず。
Exception in thread "main" java.lang.NoClassDefFoundError: helloworld (wrong nam
e: HelloWorld)
は、"helloworld"というクラスが見つからないというエラーですね。Javaの場合大文字小文字を区別するのですが小文字で"helloworld"と書いてしまったんじゃないかな。

今回はデフォルトパッケージを使っているようですがパッケージ宣言をした場合にはコンパイルと実行がちょっとややこしくなります。

Javaの場合は原則としてクラス名 = ファイル名です。パッケージを宣言する場合はフォルダ階層とパッケージ名を合わせる必要もあります。
「原則」と言ったのは、ネストしたクラスや内部クラスなどの場合は他のjavaファイル内に宣言するのと、その場合ちょっと特殊なclassファイルができるからですね。まぁ例外事項だと思って差し支えないでしょう。

# re: Java での開発の勉強をしてみる(4) コマンドラインからコンパイルと実行 2009/02/26 12:48 凪瀬

参考にjavaコマンドとjavacコマンドの公式のドキュメントを張っておきますね。
http://java.sun.com/javase/ja/6/docs/ja/technotes/tools/windows/java.html
http://java.sun.com/javase/ja/6/docs/ja/technotes/tools/windows/javac.html

# re: Java での開発の勉強をしてみる(4) コマンドラインからコンパイルと実行 2009/02/26 13:56 guicheng

凪瀬さん、ご指摘ありがとうございます。

試しに CLASSPATH 環境変数を削除してみても、カレントディレクトリの .class ファイルを実行することができました。
ドキュメントにも「-classpath も -cp も使用されず、CLASSPATH も設定されていない場合、ユーザークラスパスは現在のディレクトリ (.) になります」と書いてありますね。
ご指摘の通り、java.exe のオプションに小文字でクラス名を与えてしまったのが原因のようです。

# GZHoEfLVrsxWW 2011/12/12 18:17 http://www.birthcontrolremedy.com/birth-control/ya

Received the letter. I agree to exchange the articles.

# ayRHqqevpOrW 2011/12/15 23:55 http://www.discountwatchstore.com/Luminox-Watches_

I do`t see a feedback or the other coordinates from the blog administration!...

# CVxJDEkYTXzDhe 2011/12/19 21:23 http://paydayloansnocreditcheck.biz/

Somewhere in the Internet I have already read almost the same selection of information, but anyway thanks!!...

タイトル
名前
Url
コメント