- ベストアンサー
コンパイル
Javaのコンパイルが通らず悩んでいます。よい解決方法がありましたら、教えてください。 早速ですが、*.javaでコンパイルするとエラーが出ず、Hoge.javaの様にファイル名を指定すると『シンボルを見つけられません。』と、コンパイルエラーが発生してしまいます。 まず環境ですが、WindowsXP Pro SP3 で、Javaのバージョンは C:\com\st\sample\scr>java -version java version "1.5.0_10" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_10-b03) Java HotSpot(TM) Client VM (build 1.5.0_10-b03, mixed mode, sharing) で、CLASSPATHは、 CLASSPATH=.;.\WEB-INF\classes;.\WEB-INF\lib\struts-core-1.3.8.jar;C:\Tomcat5.5\common\lib\servlet-api.jar;C:\Java\JRE1.5.0\lib\ext\QTJava.zip となってます。 実際には、 C:\com\st\sample\srcというフォルダーがあります。その中にはSampleServlet.javaとSampleBean.javaとSampleBean.classの3つのファイルがあります。 SampleServlet.javaとSampleBean.javaはパッケージ管理するよう package com.st.sample.src; を記述してあり、SampleServlet.javaには import com.st.sample.src.*; も記述してあります。 そこで、 C:\com\st\sample\src>javac *.java を実行すると、コンパイルエラーは出ずに2つのclassファイルが作成されます。 しかし、個別に C:\com\st\sample\src>javac SampleBean.java を実行するとコンパイルエラーは出ないものの、 C:\com\st\sample\src>javac SampleServlet.java を実行すると、 SampleServlet.java:24: シンボルを見つけられません。 シンボル: クラス SampleBean 場所 : com.st.sample.src.SampleServlet の クラス SampleBean sb = new SampleBean(); ^ SampleServlet.java:24: シンボルを見つけられません。 シンボル: クラス SampleBean 場所 : com.st.sample.src.SampleServlet の クラス SampleBean sb = new SampleBean(); ^ というエラーが発生してしまいます。 *.javaだと問題なくコンパイルが通り、ファイル名を指定するとコンパイル通らないのでしょうか?設定が不足しているのでしょうか?ご存知でしたら、何かアドバイスを頂けないでしょうか。御願い致します。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
1です。 > JavaだとSampleBean.javaもSampleServlet.javaを呼び出すことも出来るんですね。 そうですね。 C言語等なら呼出先はリンク時に解決して実行コードに練り込まれちゃいますが Javaの場合は.classファイルには名前だけ書き込まれていて、実行時に仮想マシンが動的に解決してるみたいです。 だから互いに呼び出すようなこともできてしまうのでしょう。 コンパイル時にあったクラスが実行時に見つからないようなことがあったとしても クラスがないよというエラー(java.lang.NoClassDefFoundError)がthrowされるだけです。 クラス名・メソッド名・フィールド名を文字列で指定して呼び出せるリフレクションのような機能もあります。 じかに実行コードをたたくのではなく仮想マシンを通していることによる柔軟性なのでしょうね。 > Javaでは*.javaでコンパイルするのが慣例というか無難なんでしょうかね。 どうなんでしょうね。私のスキルはすべて自己流なので…w 自分はNo.1の回答にあげた経験からそのようにしていますが、 *.javaを指定したときにコンパイラが柔軟に動くように作られているところを見ると、 それが推奨なのかな?と思ってはいます。
その他の回答 (2)
- HarukaV49
- ベストアンサー率53% (48/89)
(1)>C:\com\st\sample\src>javac SampleBean.java (ソース(パッケージ)フォルダがルートにあるのは何故ですか?) (2)>CLASSPATH=.;.\WEB-INF\classes;.\WEB-INF\lib \struts-core-1.3.8.jar;C:\Tomcat5.5\common\lib \servlet-api.jar;C:\Java\JRE1.5.0\lib\ext\QTJava.zip (ソースフォルダにクラスパスが通ってないのは何故ですか?) (3)>C:\com\st\sample\src>javac *.java (コンパイルは、パッケージごとに移動しながら1つずつ手作業で行うんですか?) (4)>*.javaでコンパイルするのが慣例というか無難なんでしょうかね。 (1つのクラスの変更でプロジェクトの全ファイルをリコンパイルなんて...) 全ては、統合開発環境を導入すれば簡単に解決する問題です。 このままでは、独りよがりの非常識なJavaの知識が身に付いてしまうでしょう。 導入するかどうかは別にしても、まずは、統合開発環境の解説書を入手して 一読されることを強くお勧めします。
お礼
せっかくアドバイスを頂いていたのに返信せずに、失礼いたしました。 HarukaV49様が仰られているとおり、Eclipseにて開発を進めているところです。色々と書籍など頼りに勉強している最中ではありますが、色々 HarukaV49様に指摘を頂いた点も少しずつですが解って参りました。 独りよがりの非常識なJavaの知識にならない為にも努力していく所存です。本当に有難う御座いました。そして、本当に失礼致しました。
- osumitan
- ベストアンサー率33% (102/307)
SampleBean.javaはSampleServlet.javaを呼び出しておらず、 SampleServlet.javaはSampleBean.javaを呼び出してるのでしょうか? であれば、SampleBean.javaは単体でもコンパイルできるでしょうし、 SampleServlet.javaはSampleBean.classが見つからなければコンパイルエラーでしょうね。 別々にコンパイルするとしても、SampleBean.javaを先にやって、次にSampleServlet.javaをやれば通るでしょう。 (もちろんclassファイルの出力先にCLASSPATHが通っていなければダメでしょうけど) 本来は呼び出される側を先にコンパイルし、あとで呼び出す側をコンパイルするのが順序なのでしょうし、 C言語なんかはけっこうそういう順序を意識しなければいけなかったりしますが、 Javaだと*.javaでガバッと指定すれば、コンパイラがうまいことやってくれるみたいですね。 たとえば質問の例で仮にSampleBean.javaもSampleServlet.javaを呼んでいたとすれば、 どっちを先にコンパイルしてもエラーということになってしまいますけど、 *.javaでやればOKです。 話は変わりますが、例えばクラスAとクラスBがあったとして、 クラスAはクラスBのstatic finalなフィールドを参照しているとします。 そのフィールドの値を変更しなければならなくなりました。 修正されるソースはBだけだから、Bだけコンパイルすればいいや… とやると、クラスAは古い値のまま動いてしまいます。 なぜならstatic finalなフィールドは、呼び出し側から実行時に参照されるのではなく、 呼び出し側をコンパイルするとき、呼び出し側クラスに取り込んでしまうのです。 だから上記の例でクラスBだけコンパイルしても、クラスAの方は古い値のままです。 こういうことがあるので、自分は必ず*.javaで関連クラスをすべて同時にコンパイルするようにしています。
補足
osumitanさん、ご丁寧な回答ありがとうございました。 説明が言葉足らずになって申し訳ございません。予想されている通り、 SampleBean.javaはSampleServlet.javaを呼び出しておらず、SampleServlet.javaはSampleBean.javaを呼び出してます。 JavaだとSampleBean.javaもSampleServlet.javaを呼び出すことも出来るんですね。(ありがとうございます。勉強になりました。) > 話は変わりますが、例えばクラス...も知りませんでした。本当に勉強になります。 Javaでは*.javaでコンパイルするのが慣例というか無難なんでしょうかね。
お礼
せっかくアドバイスを頂いていたのに返信せずに、失礼いたしました。 その後、私なりに書籍で勉強して、osumitan様がいわんとしていること、私がどんな変な質問をしていたのかが解りました。 本当に丁寧にご回答を頂きながら、返事もせず大変失礼致しました。また、本当に有難う御座いました。