- PR -

コンパイルエラーについて

投稿者投稿内容
てーらーめいど
会議室デビュー日: 2007/04/24
投稿数: 17
投稿日時: 2007-04-24 18:54
初めまして。
基本的な事かも知れませんが、教えてもらえるでしょうか。

以下のフォルダ構成でソースを作りました。

C:¥Work
|-------¥com¥test¥app¥Exec.java
|-------¥com¥test¥etc¥Hello.java

コード:
Exec.java:
package com.test.app;

import com.test.etc.Hello;

public class Exec {

	public static void main(String[] args) {
		Hello samp = new Hello();
		System.out.println(samp.hello());
	}
	
}

Hello.java:
package com.test.etc;

public class Hello {

	public String hello() {
		return "Hello World!";
	}
	
}



C:¥Work>javac -classpath . com¥test¥app¥Exec.java
だとコンパイルが上手く行くのですが、

C:¥>javac -classpath C:¥Work com¥test¥app¥Exec.java
だと
エラー: com¥test¥app¥Exec.java を読み込めません。
とエラーが発生します。

classpassをsourcepathに変更してもエラーが発生します。
クラスパスの設定が間違っているでしょうか?

よろしくお願いします。
あすか
ぬし
会議室デビュー日: 2006/07/12
投稿数: 309
投稿日時: 2007-04-24 19:24
C:¥>javac -classpath C:¥Work com¥test¥app¥Exec.java
をわかりやすく解説しますと

C:¥com¥test¥app¥Exec.java
をclasspath C:¥Work でコンパイルする
という意味です。
C:¥com¥test¥app¥Exec.javaというファイルは存在していないので
(C:¥)com¥test¥app¥Exec.java を読み込めません。
というエラーが出ます。

-classpathを-sourcepathに変更すると
C:¥com¥work¥test¥app¥Exec.java
コンパイルする
になり、今度はHello.javaが見えなくなってしまいます。

C:¥でコンパイルを行うのであれば
-classpathと-sourcepathを両方指定するべきです。
てーらーめいど
会議室デビュー日: 2007/04/24
投稿数: 17
投稿日時: 2007-04-25 11:42
あすかさん、こんにちは。

教えて頂いたように、実行してみましたが結果は同じでした。

1.クラスパス指定
C:¥>javac -classpath C:¥Work com¥test¥app¥Exec.java
エラー: com¥test¥app¥Exec.java を読み込めません。

2.ソースパス指定
C:¥>javac -sourcepath C:¥Work com¥test¥app¥Exec.java
エラー: com¥test¥app¥Exec.java を読み込めません。

3.両方指定
C:¥>javac -classpath C:¥Work -sourcepath C:¥Work com¥test¥app¥Exec.java
エラー: com¥test¥app¥Exec.java を読み込めません。

ググってみたのですが、有効な情報が得られませんでした。
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2007-04-25 13:00
以下のようにするとできた(1.4.2_3)
#たぶんバージョンは関係ないと思われ

javac -classpath work work¥com¥test¥app¥Exec.java

-sourcepathはあってもなくても同じでした。
今回の場合、2つのクラスのルートパスが¥workと同じため、-classpathのみの指定でうまくいったのかもしれません。
たとえば、Hello.javaをwork_common¥com¥test¥etc¥Hello.javaに置く場合は、-sourcepath work_commonを指定する必要があると思われます。
てーらーめいど
会議室デビュー日: 2007/04/24
投稿数: 17
投稿日時: 2007-04-25 13:17
かずくんさん、ありがとうございます。

指定された構文でできました!
C:¥>javac -classpath C:¥Work Work¥com¥test¥app¥Exec.java


パッケージ指定とクラスパスを理解するために色々と試しているのですが
また問題に当たりました。
コンパイルする場所を変更して行うと、コンパイルエラーがまた発生します。

1.クラスパス指定
C:¥Temp>javac -classpath C:¥Work Work¥com¥test¥app¥Exec.java
エラー: Work¥com¥test¥app¥Exec.java を読み込めません。

2.ソースパス指定
C:¥Temp>javac -sourcepath C:¥Work Work¥com¥test¥app¥Exec.java
エラー: Work¥com¥test¥app¥Exec.java を読み込めません。

3.両方指定
C:¥Temp>javac -classpath C:¥Work -sourcepath C:¥Work Work¥com¥test¥app¥Exec.java
エラー: Work¥com¥test¥app¥Exec.java を読み込めません。

根本的な考え方が間違っているでしょうか?
マーサ
ベテラン
会議室デビュー日: 2004/11/26
投稿数: 87
投稿日時: 2007-04-25 13:26
引用:

てーらーめいどさんの書き込み (2007-04-24 18:54) より:

C:¥Work>javac -classpath . com¥test¥app¥Exec.java
だとコンパイルが上手く行くのですが、

C:¥>javac -classpath C:¥Work com¥test¥app¥Exec.java
だと
エラー: com¥test¥app¥Exec.java を読み込めません。
とエラーが発生します。


単純な事ですよ。
前者はカレントが”C:\Work”で後者は”C:\”になってますよね?
なので、後者からは”com¥test¥app¥Exec.java”が参照出来ないと言っています。
実際のパスは”C:\work\com¥test¥app¥Exec.java”なのに、
”C:\com¥test¥app¥Exec.java”を指定している為、発生しているのでは無いでしょうか?

javacの実行場所とソースのパスの関係を考えて見てください。
C:\Tempでも同様です

#見逃しがあったため、修正

[ メッセージ編集済み 編集者: マーサ 編集日時 2007-04-25 13:28 ]
てーらーめいど
会議室デビュー日: 2007/04/24
投稿数: 17
投稿日時: 2007-04-25 18:17
マーサさん、こんにちは。

java(javac)がどこにあるクラス(ソース)か分かるようにしてやるのが
classpath(sourcepath)オプションと理解しています。

ですので、
C:¥>javac -classpath C:¥Work com¥test¥app¥Exec.java
は、C:¥Workフォルダからパッケージcom.test.appのExec.javaをコンパイルしなさい
という構文だと思っていたのですが、何故か
C:¥>javac -classpath C:¥Work Work¥com¥test¥app¥Exec.java
じゃないとエラーが発生しました。

次にエラーが発生したのは、コンパイル実行する場所を変えただけなので
意味的には
C:¥Temp>javac -classpath(sourcepath) C:¥Work Work¥com¥test¥app¥Exec.java
でコンパイルが通ると思うのですが。。。
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2007-04-26 00:13
少し挙動を追っかけてみました。
引用:

てーらーめいどさんの書き込み (2007-04-25 18:17) より:

java(javac)がどこにあるクラス(ソース)か分かるようにしてやるのが
classpath(sourcepath)オプションと理解しています。


この部分については、この理解で問題ないと思います。

引用:

ですので、
C:¥>javac -classpath C:¥Work com¥test¥app¥Exec.java
は、C:¥Workフォルダからパッケージcom.test.appのExec.javaをコンパイルしなさい
という構文だと思っていたのですが、何故か
C:¥>javac -classpath C:¥Work Work¥com¥test¥app¥Exec.java
じゃないとエラーが発生しました。


ここは正しくないです。
まず基本の
C:¥>javac com¥test¥app¥Exec.java
は、C:¥com¥test¥app¥Exec.javaをコンパイルする、という意味です。
たとえclasspathを追加しようが、sourcepathを追加しようが、この前提は崩れません。

つまり、そんなファイルは無いため、コンパイラはコンパイルできねーぞと言ってきます。
これはコンパイラがExecクラスをカレントディレクトリからたどれないことが原因です。
すなわち、コンパイラが、C:¥com¥test¥app¥Exec.class (or Exec.java)が無いと怒っているのです(ぷんぷん)。

従って、Execクラスをたどることができるよう、work¥com¥test¥app¥Exec.javaのように指定してあげなければなりません。

そこで、
C:¥>javac work¥com¥test¥app¥Exec.java
とすると、Execはコンパイルが成功します。
ここで、ExecはHelloクラスを参照しています。コンパイラは依存しているクラスも自動的にコンパイルを試みてくれます(ありがたいことです)。

Helloクラスはcom.test.etcパッケジに属しているため、同様に、
com¥test¥etc¥Hello.javaを探します。しかしそんなところにファイルは無いのでHello.javaをコンパイルできず、結果Helloクラスが見つからないとのエラーが出ます。

これを解決するためには、Hello.javaをたどれる正しいルートを教えてあげなければなりません。
これが-classpath workを指定してあげるということです。

つまり、
引用:

次にエラーが発生したのは、コンパイル実行する場所を変えただけなので
意味的には
C:¥Temp>javac -classpath(sourcepath) C:¥Work Work¥com¥test¥app¥Exec.java
でコンパイルが通ると思うのですが。。。


のように、カレントディレクトリを変えたのならば、コンパイルするファイルのパスを変えてあげなければなりません。


ほかにも例を挙げておくと、Hello.javaをC:¥work_work¥com¥test¥appに置き、C:をカレントディレクトリとした場合、どうなるでしょうか?

先ほどと同じように、
javac -classpath work work¥com¥test¥app¥Exec.java
と実行した場合、Exec.javaは問題なく、コンパイルできますが、Helloはまたもやたどれなくなってしまったため、コンパイルエラーとなります。
そりゃそうだ。work¥com¥test¥etc¥Hello.javaなんて無いからね。

そこでクラスパスをworkからwork_workに変更してあげます。
すなわち、javac -classpath work_work work¥com¥test¥app¥Exec.javaとなります。


最後にもう一つ、Execクラスがcom.test.etc.Hello2クラスに依存していると仮定し、Hello2.javaをC:¥com¥test¥appに置き、C:をカレントディレクトリとした場合、どうなるでしょうか?

この状況に対し、
javac -classpath work_work work¥com¥test¥app¥Exec.java
とした場合、コンパイラは、ExecクラスとHelloクラスは見つけることはできますが、
Hello2クラスが見つからないとご立腹になってしまいます。
この場合、コンパイラはC:¥work_work¥com¥test¥etc¥Hello2.javaを探したんでしょうね、きっと。

なぜ、カレントディレクトリからたどれるのに、みてくれないのでしょうか?
これはクラスパスにカレントディレクトリが指定されていないからです。
故に、javac -classpathwork;. work com¥test¥app¥Exec.java
のように、カレントディレクトリもクラスパスに追加してあげます。

#こんだけ例をあげれば、十分かい?
##うーむ。あまりまとまってねーな。こりゃ。

スキルアップ/キャリアアップ(JOB@IT)