CodeGym /コース /JAVA 25 SELF /マルチモジュールプロジェクトのビルド: Maven、Gradle、IDEA

マルチモジュールプロジェクトのビルド: Maven、Gradle、IDEA

JAVA 25 SELF
レベル 60 , レッスン 4
使用可能

1. モジュール化プロジェクトのビルド: 基本原則

コンパイラとモジュールパス (module-path)

モジュール登場以前は、アプリケーションは classpath(Java がクラスを探すためのディレクトリや JAR の単なるリスト)でコンパイル/実行されていました。モジュールシステムでは新たに module-path が加わりました。いまやコンパイラと JVM は、クラスの所在だけでなく、それらがどのモジュールに属するか、どんな依存関係を持つか、どのパッケージをエクスポートしているかも把握する必要があります。

重要なポイント:

  • モジュール化プロジェクトでは --module-path-classpath の代わりに使います。
  • コンパイラと JVM は、アプリケーションに必要なすべてのモジュール(およびその依存関係)を可視化できる必要があります。

例: モジュールを手動でコンパイル

たとえば、coreapp という 2 つのモジュールがあり、appcore に依存しているとします。

ディレクトリ構成:

project-root/
  core/
    src/
      main/
        java/
          module-info.java
          com/example/core/...
  app/
    src/
      main/
        java/
          module-info.java
          com/example/app/...

手動コンパイル (デモ):

# まず core をコンパイルする
javac -d out/core core/src/main/java/module-info.java core/src/main/java/com/example/core/*.java

# 次に app。module-path で core を指定してコンパイル
javac --module-path out/core -d out/app app/src/main/java/module-info.java app/src/main/java/com/example/app/*.java

実行:

java --module-path out/core:out/app -m app/com.example.app.Main

実プロジェクトでは手作業は不要です — Maven/GradleIDE を使いましょう。

2. Maven: マルチモジュールプロジェクトのビルド

Maven におけるマルチモジュールプロジェクトの構成

Maven は長年にわたり複数モジュール(サブモジュール)構成をサポートしています。Java のモジュールシステムが登場してからは、これらの「Maven のモジュール」が Java モジュールと一致することが多いですが、必ずしもそうとは限りません。Maven モジュールは単なるサブプロジェクトであり、Java モジュールは module-info.java に記述されたものを指します。通常は 1 つの Maven モジュール = 1 つの Java モジュールです。

典型的な構成:

myproject/
  pom.xml                # Parent POM
  core/
    pom.xml              # core モジュール
    src/main/java/
      module-info.java
      com/example/core/...
  app/
    pom.xml              # app モジュール
    src/main/java/
      module-info.java
      com/example/app/...

親 POM の例 (myproject/pom.xml):

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>myproject</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>
  <modules>
    <module>core</module>
    <module>app</module>
  </modules>
</project>

core モジュールの POM の例 (core/pom.xml):

<project>
  <parent>
    <groupId>com.example</groupId>
    <artifactId>myproject</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <artifactId>core</artifactId>
  <dependencies>
    <!-- ここに依存関係(他のモジュールや外部ライブラリなど)を追加できます -->
  </dependencies>
</project>

app モジュールの POM の例 (app/pom.xml):

<project>
  <parent>
    <groupId>com.example</groupId>
    <artifactId>myproject</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <artifactId>app</artifactId>
  <dependencies>
    <dependency>
      <groupId>com.example</groupId>
      <artifactId>core</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
  </dependencies>
</project>

重要:

  • appcore が必要な場合、app モジュールの module-info.javarequires core; を記述する必要があります。
  • <dependency><module> を正しく記述していれば、Maven が依存関係を解決してくれます。

Maven は module-info.java をどう扱うか

  • Maven は module-info.java を他のクラスと一緒に自動的にコンパイルします。
  • モジュールの依存関係がある場合、Maven はコンパイルと実行時にそれらを module-path に追加します。
  • 古いプラグインや Java 9 未満を使っていると、モジュールシステムは動作しません。

Maven 経由でモジュール化アプリを実行する

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.10.1</version>
      <configuration>
        <release>21</release> <!-- あるいは使用している Java バージョン -->
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>exec-maven-plugin</artifactId>
      <version>3.1.0</version>
      <configuration>
        <mainClass>com.example.app.Main</mainClass>
        <commandlineArgs></commandlineArgs>
      </configuration>
    </plugin>
  </plugins>
</build>
mvn clean install
mvn -pl app exec:java

Maven とモジュール使用時のよくある誤り

エラー: 「module not found」。 正しい module-path を指定していないか、依存アーティファクトのための <dependency> が記述されていません。

モジュール名の重複。 プロジェクト内に同名のモジュールが 2 つあってはなりません(例: 2 つの module core)。

exports/requires の不足。 パッケージをエクスポート(exports)していない、または依存(requires)を宣言していない場合、コンパイルエラーになります。

classpath と module-path の混在。 モジュールをサポートしない古いプラグイン/設定は使わないでください。予期しないエラーの原因になります。

3. Gradle: マルチモジュールプロジェクトのビルド

Gradle プロジェクトの構成

myproject/
  settings.gradle
  build.gradle
  core/
    build.gradle
    src/main/java/module-info.java
    src/main/java/com/example/core/...
  app/
    build.gradle
    src/main/java/module-info.java
    src/main/java/com/example/app/...

settings.gradle

rootProject.name = 'myproject'
include 'core', 'app'

build.gradle(ルート)

subprojects {
    apply plugin: 'java'

    java {
        toolchain {
            languageVersion = JavaLanguageVersion.of(21) // もしくは使用している Java のバージョン
        }
    }

    repositories {
        mavenCentral()
    }
}

core 用の build.gradle

plugins {
    id 'java'
}

group = 'com.example'
version = '1.0-SNAPSHOT'

app 用の build.gradle

plugins {
    id 'java'
    id 'application'
}

group = 'com.example'
version = '1.0-SNAPSHOT'

dependencies {
    implementation project(':core')
}

application {
    mainModule = 'app' // あなたの Java モジュール名
    mainClass = 'com.example.app.Main'
}

ビルドと実行

./gradlew build
./gradlew :app:run

Gradle は module-info.java を検出すると module-path を自動的に解決します。もしうまく動作しない場合は、Gradle 本体とプラグインのバージョンが十分に新しいか確認してください。

4. IntelliJ IDEA: モジュール化プロジェクトの作成と設定

モジュール化プロジェクトの作成

  • File → New → Project → Java → 「Create module-info.java」を有効化。
  • マルチモジュールプロジェクトの場合: File → New → Module — プロジェクトに新しいモジュールを追加します。
  • Maven/Gradle を使う場合は、pom.xml または build.gradle でプロジェクトをインポートするだけです。

IDEA での構成表示

  • Project View では、各モジュールが別のブランチとして表示されます。
  • 各モジュールには独自の module-info.java とソースがあります。
  • IDEA は、どのモジュールがどのパッケージをエクスポート/要求しているか(exports/requires)を示してくれます。
  • パッケージのエクスポートや依存宣言を忘れている場合、IDEA がエラーとしてハイライトします。

module-path の確認、main クラスの実行

  • Run/Debug Configurations で次を指定します:
    • Main class(例: com.example.app.Main
    • Module(例: app
  • IDEA が module-path を自動で処理します。
  • Maven/Gradle から実行する場合は、対応する設定を使用してください(例: app [run])。

外部モジュールとライブラリのインポート

  • 外部ライブラリを使う場合(例: requires java.sql; やサードパーティの JAR)— Maven/Gradle で依存関係を追加します。
  • ライブラリがモジュール化されていない(module-info.java がない)場合は、自動的に「unnamed module」に追加されます(多くのライブラリではこれで問題ありません)。

5. 実践: 簡単なマルチモジュールプロジェクトを作る

ステップ 1. プロジェクト構成の作成

myproject/
  core/
    src/main/java/module-info.java
    src/main/java/com/example/core/HelloService.java
  app/
    src/main/java/module-info.java
    src/main/java/com/example/app/Main.java

HelloService.java(core):

package com.example.core;

public class HelloService {
    public String getHello() {
        return "core モジュールからの挨拶!";
    }
}

module-info.java(core):

module core {
    exports com.example.core;
}

Main.java(app):

package com.example.app;

import com.example.core.HelloService;

public class Main {
    public static void main(String[] args) {
        HelloService service = new HelloService();
        System.out.println(service.getHello());
    }
}

module-info.java(app):

module app {
    requires core;
}

ステップ 2. Maven でビルドして実行

プロジェクトのルートに親の pom.xml を作成し、2 つのサブプロジェクト(core/pom.xmlapp/pom.xml)を上記のように用意します。app/pom.xmlcore への依存を追加します。

mvn clean install
mvn -pl app exec:java

ステップ 3. Gradle でビルドして実行

settings.gradle、ルートの build.gradle、各モジュール用の build.gradle を作成します。app/build.gradlecore への依存と mainClass を設定します。

./gradlew build
./gradlew :app:run

ステップ 4. IntelliJ IDEA でのインポートと実行

  • File → Open からプロジェクトのルートを開きます。
  • IDEA は Maven/Gradle の構成を認識し、モジュールを作成します。
  • 各モジュールで module-info.java を開くと、IDEA はモジュール間の関係を表示します。
  • コンテキストメニューから Main.java を実行(「Run Main.main()」)— IDEA が module-path を自動設定します。

6. モジュール化プロジェクトのビルドでよくあるエラー

エラー1: module-path が正しくない。 実行やコンパイル時に「module not found」や「package is not visible」といったメッセージが出る場合、正しい module-path を指定していない、または pom.xml/build.gradle に依存関係を追加し忘れている可能性があります。

エラー2: モジュール名の重複。 プロジェクト内に同名のモジュール(例: 2 つの module core)が存在してはなりません。これはコンパイルエラーにつながります。

エラー3: パッケージの未エクスポート。 クラスが module-info.javaexports でエクスポートされていないパッケージにある場合、たとえそのクラスが public でも他モジュールからは見えません。利用しようとするとコンパイルエラーになります。

エラー4: requires の未宣言。 他モジュールのクラスを使っているのに、module-info.javarequires を記述していない場合、コンパイラがエラーを出します。

エラー5: 外部ライブラリとの非互換。 module-info.java のないライブラリ(「unnamed module」に入る)は通常問題ありませんが、構成によっては追加の設定が必要になることがあります。

エラー6: 別のモジュールから起動している。 IDEAMaven/Gradle の実行構成で、main クラスやモジュールが誤っているとアプリは起動しません。MainmainModule/module、使用中のプロファイルを確認してください。

1
タスク
JAVA 25 SELF, レベル 60, レッスン 4
ロック未解除
マルチモジュールプロジェクトの要塞構築 🏰
マルチモジュールプロジェクトの要塞構築 🏰
1
タスク
JAVA 25 SELF, レベル 60, レッスン 4
ロック未解除
アプリケーションの心臓をMavenで起動 ✨
アプリケーションの心臓をMavenで起動 ✨
1
アンケート/クイズ
モジュールとプロジェクト構成、レベル 60、レッスン 4
使用不可
モジュールとプロジェクト構成
モジュールとプロジェクト構成
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION