メインコンテンツへスキップ
  1. ノート/
  2. Java/

Java のパッケージ設定と紹介

·3221 文字·7 分· loading · loading · · ·
ICE345
著者
ICE345
CS Student | System | Linux | OCaml

以下は、複数の Java ファイルをパッケージとして整理し、パッケージを import し、さらに JAR ファイルへ打包する流れをまとめた詳細なチュートリアルです。

1. Java パッケージを作成する
#

1.1 ディレクトリ構造
#

com.example.myappというパッケージを作ると仮定すると、ディレクトリ構造は以下のようになります。

一般的に、パッケージ名はディレクトリ構造名です。そのため、パッケージを実行・コンパイルする時は、通常ディレクトリのルート構造下でコマンドを実行します。たとえばcom.example.myappというパッケージがmyapp/src/com/example/myappに対応している場合、srcルートディレクトリでコマンドを実行する必要があります。
myapp/
├── src/
│   └── com/
│       └── example/
│           └── myapp/
│               ├── HelloWorld.java
│               └── Utils.java
└── bin/

1.2 Java ファイルを書く
#

HelloWorld.java:

package com.example.myapp;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
        Utils.printMessage("This is a message from Utils.");
    }
}

Utils.java:

package com.example.myapp;

public class Utils {
    public static void printMessage(String message) {
        System.out.println(message);
    }
}

2. Java ファイルをコンパイルする
#

  1. ターミナルを開き、srcディレクトリへ移動します。

    cd path/to/myapp/src
  2. javacで Java ファイルをコンパイルします。

    javac com/example/myapp/*.java -d ../../bin

    ここで-d ../../binは、コンパイルで生成された.classファイルをbinディレクトリへ置くという意味です。

3. Java プログラムを実行する
#

  1. binディレクトリにいることを確認します。

    cd ../../bin
  2. プログラムを実行します。

    java com.example.myapp.HelloWorld

4. JAR ファイルを作成する
#

  1. 引き続きbinディレクトリで、jarコマンドを使って JAR ファイルを作成します。

    jar cvf myapp.jar com/example/myapp/*.class

    ここでcは作成、vは詳細出力、fは JAR ファイル名の指定を表します。

  2. JAR ファイルが作成されたか確認します。

    ls

    myapp.jarファイルが見えるはずです。

5. JAR ファイルを実行する
#

  1. JAR ファイルを実行する時は主クラスを指定する必要があります。HelloWorldクラスの場合、MANIFEST.MFで主クラスを指定することもできますし、コマンドラインから直接実行することもできます。
    java -cp myapp.jar com.example.myapp.HelloWorld

この方法なら、JAR ファイル内の任意のクラスを実行できます。cpコマンドで指定すればよいです。

6. JAR ファイルに主クラスを追加する
#

JAR ファイルを直接実行できるようにするには、MANIFEST.MFに主クラスを追加します。

  1. MANIFEST.MFというファイルを作り、内容を以下のようにします。

    Manifest-Version: 1.0
    Main-Class: com.example.myapp.HelloWorld
  2. JAR ファイル作成時にMANIFEST.MFを指定します。

    jar cvfm myapp.jar MANIFEST.MF com/example/myapp/*.class

7. JAR ファイルを直接実行する
#

これで、主クラスを指定せずに JAR ファイルを直接実行できます。

java -jar myapp.jar

8. サードパーティパッケージを使う
#

Java ファイルで使うパッケージが他人によって打包されたものなら、コンパイル時に引数を追加してそのパッケージを使えるようにします。例:

コンパイル

javac --module-path /path/to/javafx-sdk/lib --add-modules javafx.controls HappyFaceFX.java

実行

java --module-path /path/to/javafx-sdk/lib --add-modules javafx.controls HappyFaceFX

9. 自分でローカルに打包したパッケージを使う
#

まず、元のディレクトリ構造は以下です。

myapp
├── bin
│   ├── com
│   │   └── example
│   │       ├── myapp
│   │           ├── HelloWorld.class
│   │           └── Utils.class
│   │       
│   │        
│   └── myapp.jar
└── src
    └── com
        └── example
            ├── app
            │   ├── HelloWorld.java
            │   └── Utils.java
            └── test
                └── MainApp.java

次に、新しい構造を以下のように作成します。

myapp
├── bin
│   ├── com
│   │   └── example
│   │       ├── myapp
│   │       │   ├── HelloWorld.class
│   │       │   └── Utils.class
│   │       └── test
│   │           └── MainApp.class
│   └── myapp.jar
└── src
    └── com
        └── example
            ├── app
            │   ├── HelloWorld.java
            │   └── Utils.java
            └── test
                └── MainApp.java

このtestフォルダの Java ファイルは以下です。

package com.example.test;

import com.example.myapp.Utils; // 导入 Utils 类

public class MainApp {
    public static void main(String[] args) {
        Utils.printMessage("Hello from MainApp!");
    }
}

com.example.myappパッケージ内のUtilsクラスを import し、このファイルをcom.example.testパッケージとして設定しています。

このファイルのコンパイル方法
#

  1. exampleフォルダ下のすべての Java ファイルをまとめてコンパイルする。こうすれば依存関係の問題が起きにくい
  2. コンパイル時にパス(-cp)を設定する。srcフォルダ下で以下を実行:javac -cp ../bin com/example/test/MainApp.java -d ../bin
  3. -cpと jar パッケージを組み合わせてもよい。srcフォルダ下で以下を実行:javac -cp ../bin/myapp.jar com/example/test/MainApp.java -d ../bin

==最後に、パッケージを設定した時点でディレクトリ構造があるため、javacでファイルをコンパイルして具体的なディレクトリへ出力すると、対応するディレクトリ構造も生成されます。つまりフォルダが増えます。==

このファイルの実行方法
#

実行コマンド:

java com.example.test.MainApp  

クラスファイルへのリンクが必要かどうかは状況次第です。同じパッケージルートcom/example下にあるなら-cpは不要なようです。同じルート下にない場合は-cpが必要です。

要するに、実行できなければ手動で-cpを付ければよいです。

10. --module-path-cp の違い
#

--module-path-cp(または--class-path)は Java の異なるオプションで、異なる場面で使います。Java には二つのコード整理方式があるためです:モジュールシステムクラスパス

違い:
#

1. -cp--class-path
#

-cpクラスパスを指定するオプションで、従来の Java プロジェクト構造に適しています。つまり、すべての.classファイルと JAR ファイルをクラスパスで管理・読み込みます。

  • 使用場面:従来型 Java プロジェクトで.classファイルや JAR パッケージを探す時。
  • 適したプロジェクト:Java 9 で導入されたモジュールシステムを使っていないプロジェクト、または依然としてクラスパスで管理しているライブラリや依存。

javac -cp /path/to/library.jar YourProgram.java
java -cp /path/to/library.jar YourProgram
2. --module-path-p
#

--module-pathモジュールシステム用のオプションです。これは Java 9 で導入された機能です。モジュールシステムでは、コードと依存(例:JAR ファイル)はモジュールとして打包され、各モジュールは明確な依存関係と公開 API を持ちます。

  • 使用場面:モジュールパス(つまりモジュール化された JAR ファイル)を指定する時。Java 9 以上のプロジェクト、特に Java のモジュールシステムを使うプロジェクトに適しています。
  • 適したプロジェクト:コードと依存をモジュールとして整理するプロジェクト。たとえば JavaFX はモジュールシステムベースのライブラリです。

javac --module-path /path/to/modules --add-modules javafx.controls YourProgram.java
java --module-path /path/to/modules --add-modules javafx.controls YourProgram

なぜ JavaFX には--module-pathが必要なのか?
#

JavaFX は Java 9 以降、独立したモジュールになりました(JDK には含まれなくなりました)。そのため、JavaFX アプリをコンパイル・実行する時は、Java コンパイラと実行環境に JavaFX モジュールの場所を教える必要があります。これが--module-pathで JavaFX モジュールのパスを指定する理由です。

例の説明

javac --module-path /path/to/javafx-sdk/lib --add-modules javafx.controls HappyFaceFX.java
  • --module-path:JavaFX SDK のパスを指定します。ここには JavaFX のモジュール化 JAR ファイルが含まれています。
  • --add-modules javafx.controls:コンパイラまたは実行時にjavafx.controlsモジュールを読み込むよう明示します。これは JavaFX が提供する主要 UI コントロールモジュールです。

いつ-cp--module-pathを使うか?
#

  • -cpを使う:非モジュール化 Java プロジェクトや依存を使う場合は、従来通りクラスパス(-cp)を使います。
  • --module-pathを使う:プロジェクトまたは依存がモジュール化されている場合、特に Java 9 のモジュールシステムを使う場合、たとえば JavaFX ではこちらを使います。

小まとめ
#

  • -cpは従来のクラスパス管理に適しています。
  • --module-pathはモジュール化プロジェクトやライブラリ(Java 9 のモジュールシステムなど)に適しています。

まとめ
#

ここまでで、以下の手順を完了しました。

  1. Java パッケージを作成する。
  2. Java ファイルを書いてコンパイルする。
  3. Java プログラムを実行する。
  4. JAR ファイルを作成する。
  5. JAR ファイルに主クラスを追加し、直接実行する。

この方法により、コードを整理し、プロジェクト管理を簡略化し、配布しやすくできます。