7
7

More than 3 years have passed since last update.

Java:「メインクラスを検出およびロードできませんでした」の解決法

Last updated at Posted at 2021-02-10

はじめに

当方はJavaの初学者で、今までは1つのソースコード内でクラスを作成しプログラミングを行ってきたが、学習が進むにつれてクラスの数が増えてきたため、パッケージを利用することにした。
しかし、パッケージを利用して同様の方法で実行しようとしたところ、少し手こずったため、備忘録として残しておく。

現象

パッケージの利用で複数のソースコードをコンパイルし、実行しようとしたところ...
・コンパイルはできるのに実行ができない!
・エラー: メインクラスを検出およびロードできませんでした
・原因: java.lang.NoClassDefFoundError: Sample2/Sample2 (wrong name: Sample2)

今までの実行方法

Sample1.java
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フォルダ内に格納した。
(ディレクトリ構造は以下の通り)

スクリーンショット 2021-02-10 23.23.17.png

Sample2.java
package Sample2;

public class Sample2 {
    public static void main(String[] args){
        Student s = new Student("山田");
    } 
}
Student.java
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)

この通り、コンパイルは滞りなくできたのだが、エラーとなってしまい実行ができない。
スクリーンショット 2021-02-10 23.20.18.png
(↑クラスは生成されている)

原因とその解決

原因としては、コマンドの入力が違うというありきたりなもの。
起動しようとしているクラスの指定が間違っていることが原因らしい。
何も考えずにjava 〜というコマンドで実行してきたが、パッケージを利用する際はそう簡単にはいかないらしい。

java Sample2というコマンドは、デフォルトパッケージにあるSample2.classを実行するという意味なので、こちらでパッケージを指定する場合は○○パッケージの××クラスを実行するというコマンドを入力しなければならない。

従って、正しくは...

****noMacBook-Pro:Sample2 ********$ cd /Users/********/Desktop/Sample
                                   (↑Sampleフォルダにパスを変えている)
****noMacBook-Pro:Sample ********$ java Sample2.Sample2
山田は生徒です

無事出力された。

まとめ

今回のように、パッケージ内のファイルを実行するには
java パッケージ名.クラス名
というコマンドを入力する必要がある。

あと、余談だが、パッケージ名は全て小文字というのが慣習らしい。
なので今回のようなSample2というパッケージ名はあまり良くなくて、sampleという名前の方が好まれるとか。
次からはその辺りももう少し意識して名前をつけようと思う。

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7