QA@IT

複数パッケージを含んだクラスのコンパイル後の実行エラーの回避 (手動

3528 PV

他のパッケージを含んだクラスを手動でコンパイルし、実行させる練習をしています。
なかなか上手くいかないのでご教授を伺いに来ました。

躓いているのはPackageのコンパイル後の実行です。
以下手順

Cドライブ-root-+-app---bin---Package.java 
                     +-org---etc---TestA.class 
                     +-jp-----co----media----------------TestB.class 

1この様なツリーで、Package.javaをコンパイル後に実行が成功したら

TestA success
TestA success

と表示されるTestA、Bを作成しました。

↓TestA

package org.etc;
public class TestA {
    public void write() {
        System.out.println("TestA success");
    }
}

↓TestB

package co.media;
public class TestB {
    public void write() {
        System.out.println("TestB success");
    }
}

ここまでは問題無いと思っています。
そしてPackageをappをカレントフォルダとしてコンパイル
↓Package

package bin;
import org.etc.TestA;
import co.media.TestB;

public class Package {
    public static void main(String[] args) {

        TestA pursueA = new TestA();
        pursueA.write();

        TestB pursueB = new TestB();
        pursueB.write();
    }
}

コマンドプロンプト

C:\root\app>javac -cp ../;../jp ./bin/Package.java

これでC:\root\app\binにPackage.classを作りました。

この後の実行が出来ません。
コマンドプロンプト

C:\root\app>java bin.Package
Exception in thread "main" java.lang.NoClassDefFoundError: bin/Package
Caused by: java.lang.ClassNotFoundException: bin.Package
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Could not find the main class: bin.Package. Program will exit.

以上が現在の引っかかっているところまでの手順です。
一つでも良いので間違っているところを指摘して頂けると助かります。
JAVA遣いの皆様、どうかよろしくお願いします。

回答

解決しました。
コマンドプロンプト

C:\root\app>java -cp ../;../jp; bin/Package
TestA success
TestB success

今回の自分の学び。
・コンパイルしたクラスを実行する時はパッケージの親フォルダから。
・他のパッケージを参照に取り込む時はclasspathを入力して指定。
・指定する時もパッケージの親フォルダまでを指定。
・複数あるときはセミコロン;
・相対パスは慎重に作らないと結構間違える。

編集 履歴 (0)

TestBのパッケージ名にjpが抜けていますがこれは間違いでは無いのでしょうか?

__________2015-04-14_21.00.53.png

フォルダ構成が上記であるとして、TestBのパッケージが jp.co.mediaであれば以下の様にコンパイル、実行できます。
c:\root\app で実行していることも気をつけてください。

C:\root\app>javac bin\Package.java

C:\root\app>java -cp . bin.Package
TestA success
TestB success

-cp . なので、カレントディレクトリをクラスパスとして指定しています。

Package.java と TestB.javaは以下の様になります。(といってもパッケージ coの前にjpつけただけです。)

package bin;
import org.etc.TestA;
import jp.co.media.TestB;

public class Package {
    public static void main(String[] args) {

        TestA pursueA = new TestA();
        pursueA.write();

        TestB pursueB = new TestB();
        pursueB.write();
    }
}
package jp.co.media;
public class TestB {
    public void write() {
        System.out.println("TestB success");
    }
}

なお、TestBがそれで正しい場合(jpパッケージで無い場合)は、以下の様にもできます。

C:\root\app>cd jp

C:\root\app\jp>javac co\media\TestB.java

C:\root\app\jp>cd ..

C:\root\app>javac -cp .;jp bin\Package.java

C:\root\app>java -cp .;jp bin.Package
TestA success
TestB success
編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。