#はじめに
当方はJavaの初学者で、今までは1つのソースコード内でクラスを作成しプログラミングを行ってきたが、学習が進むにつれてクラスの数が増えてきたため、パッケージを利用することにした。
しかし、パッケージを利用して同様の方法で実行しようとしたところ、少し手こずったため、備忘録として残しておく。
###現象
パッケージの利用で複数のソースコードをコンパイルし、実行しようとしたところ...
・コンパイルはできるのに実行ができない!
・エラー: メインクラスを検出およびロードできませんでした
・原因: java.lang.NoClassDefFoundError: Sample2/Sample2 (wrong name: Sample2)
#今までの実行方法
class Student {
private String name;
public Student(String _name) {
this.name = _name;
System.out.println(this.name + "は生徒です");
}
}
class Sample1 {
public static void main(String[] args){
Student s = new Student("山田");
}
}
例えば、上記のソースコード(Sampleフォルダ直下)をターミナルでコンパイル・実行すると
****noMacBook-Pro:Sample ********$ javac Sample1.java
****noMacBook-Pro:Sample ********$ java Sample1
山田は生徒です
という結果になり、特に問題なく実行できる。
#パッケージ化されたものを同様の方法で実行すると...?
1つのソースコード内のクラスを複数のソースコードに分けて、1つのパッケージとするとき、先ほどと同様の方法で実行してみる。
なお、Sample1.javaはSample2.javaとStudent.javaに分割し、Sample2フォルダ内に格納した。
(ディレクトリ構造は以下の通り)
package Sample2;
public class Sample2 {
public static void main(String[] args){
Student s = new Student("山田");
}
}
package Sample2;
public class Student {
private String name;
public Student(String _name) {
this.name = _name;
System.out.println(this.name + "は生徒です");
}
}
これらのソースコードを先ほどと同様の方法で実行してみる
(パスはSample2フォルダに変更済み)
****noMacBook-Pro:Sample2 ********$ javac Sample2.java Student.java
****noMacBook-Pro:Sample2 ********$ java Sample2
エラー: メイン・クラスSample2を検出およびロードできませんでした
原因: java.lang.NoClassDefFoundError: Sample2/Sample2 (wrong name: Sample2)
この通り、コンパイルは滞りなくできたのだが、エラーとなってしまい実行ができない。
(↑クラスは生成されている)
#原因とその解決
原因としては、コマンドの入力が違うというありきたりなもの。
起動しようとしているクラスの指定が間違っていることが原因らしい。
何も考えずにjava 〜
というコマンドで実行してきたが、パッケージを利用する際はそう簡単にはいかないらしい。
java Sample2
というコマンドは、デフォルトパッケージにあるSample2.classを実行する
という意味なので、こちらでパッケージを指定する場合は○○パッケージの××クラスを実行する
というコマンドを入力しなければならない。
従って、正しくは...
****noMacBook-Pro:Sample2 ********$ cd /Users/********/Desktop/Sample
(↑Sampleフォルダにパスを変えている)
****noMacBook-Pro:Sample ********$ java Sample2.Sample2
山田は生徒です
無事出力された。
#まとめ
今回のように、パッケージ内のファイルを実行するには
java パッケージ名.クラス名
というコマンドを入力する必要がある。
あと、余談だが、パッケージ名は全て小文字というのが慣習らしい。
なので今回のようなSample2というパッケージ名はあまり良くなくて、sampleという名前の方が好まれるとか。
次からはその辺りももう少し意識して名前をつけようと思う。