MavenでJavaプロジェクトをビルドするまで【macOS】

Javaを使用して「Hello, World」を表示する簡単なプロジェクトを作成し、Mavenでビルドするまでの手順を、macOS向けに説明します。

Mavenを使ってビルドする手順

Mavenのインストール

まず、Mavenをインストールします。Homebrewを使用してインストールできます。

bash
brew install maven

インストールが完了したら、以下のコマンドでMavenが正しくインストールされているか確認します。

bash
mvn -version
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: /opt/homebrew/Cellar/maven/3.9.9/libexec
Java version: 14.0.2, vendor: AdoptOpenJDK, runtime: /Library/Java/JavaVirtualMachines/adoptopenjdk-14.jdk/Contents/Home
Default locale: en_JP, platform encoding: UTF-8
OS name: "mac os x", version: "10.16", arch: "x86_64", family: "mac"

これで、Mavenのバージョン情報が表示されればインストールは成功です。

Mavenは、後方互換性を重視して開発されています。そのため、最新のMavenバージョンでも、多くの場合、古いバージョンのMavenで作成されたプロジェクトをビルドすることが可能です。

Mavenプロジェクトの作成

次に、Mavenプロジェクトを作成します。Mavenには、プロジェクトを簡単に作成するためのテンプレート機能が備わっています。

ターミナルで、プロジェクトを作成したいディレクトリに移動し、以下のコマンドを実行します。

bash
mvn archetype:generate -DgroupId=fun._101010 -DartifactId=helloworld -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

このコマンドの意味は以下の通りです:

  • -DgroupId=fun._101010: グループID(パッケージの逆ドメイン名)
  • -DartifactId=helloworld: プロジェクトの名前
  • -DarchetypeArtifactId=maven-archetype-quickstart: シンプルなMavenプロジェクトのテンプレート
  • -DinteractiveMode=false: 対話モードを無効にして、指定したオプションでプロジェクトを自動生成

Javaのパッケージ名は、英字(小文字)から始まり、数字やアンダースコアを使用することはできますが、数字で始まる識別子やドット(.)で区切られた部分が数字のみの場合はエラーとなります。fun.101010のように、ドットで区切られた部分に純粋な数字を使用することはできません。そのため、fun._101010のようにアンダーバーを追記してます。

プロジェクトディレクトリに移動

次に、作成されたプロジェクトのディレクトリに移動します。

bash
cd helloworld

次のような構造で、プロジェクトが生成されてました。

bash
tree
.
├── pom.xml
└── src
    ├── main
    │   └── java
    │       └── fun
    │           └── _101010
    │               └── App.java
    └── test
        └── java
            └── fun
                └── _101010
                    └── AppTest.java

Hello, World プログラムの作成

src/main/java/fun/_101010/App.javaというファイルが自動生成されています。このファイルに「Hello, World」を表示するコードが既に含まれていますが、確認しておきましょう。
java
package fun._101010;

public class App 
{
    public static void main( String[] args )
    {
        System.out.println( "Hello, World!" );
    }
}

必要であれば、ファイルをテキストエディタで開いて、内容を確認・修正してください。

Mavenでビルドする

プロジェクトのディレクトリ内で以下のコマンドを実行して、Mavenでプロジェクトをビルドします。

bash
mvn package

このコマンドを実行すると、Mavenがプロジェクトをコンパイルし、JARファイルをtargetディレクトリに生成します。

プログラムの実行

ビルドが成功したら、生成されたJARファイルを実行して「Hello, World」を表示します。

bash
java -cp target/helloworld-1.0-SNAPSHOT.jar fun._101010.App

これでターミナルに「Hello, World!」と表示されれば成功です。

毎回クラスパスの指定をするのは面倒

java -cp target/helloworld-1.0-SNAPSHOT.jar fun._101010.App コマンドでJARファイルを実行する際、fun._101010.App の部分は実行したいクラスの「完全修飾名(fully qualified name)」を指定する必要があります。完全修飾名は、そのクラスが属しているパッケージ名を含むクラス名のことです。

なぜ完全修飾名を指定するのか

Javaでは、同じ名前のクラスが異なるパッケージに存在する可能性があります。そのため、どのクラスを実行すべきかを明確に指定するために、パッケージ名を含めた完全修飾名を使用します。これにより、Javaはどのクラスを実行するかを正確に認識できます。

実行時の注意点

  • クラスパスの指定: -cp オプションで指定したJARファイルがクラスパスとして使用されます。このクラスパス内にあるクラスを指定するために、完全修飾名が必要です。
  • メインメソッドの存在: 実行しようとするクラスには、public static void main(String[] args) メソッドが必要です。このメソッドがエントリーポイントとなり、Javaプログラムが実行されます。

java -jar コマンドを使用する方法

もし、JARファイル自体に実行すべきクラスが指定されている場合は、java -jar コマンドを使用することで、パッケージ名を含むクラス名を指定せずにJARファイルを実行できます。

まず pom.xml ファイルに <build> セクションを追加し、その中に maven-jar-plugin を設定して、Main-Class を指定します。

xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>fun._101010</groupId>
  <artifactId>helloworld</artifactId>
...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.2.0</version>
        <configuration>
          <archive>
            <manifest>
              <mainClass>fun._101010.App</mainClass>
            </manifest>
          </archive>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

次に再度、Mavenでプロジェクトをビルドします。

bash
mvn package
java -jar コマンドでJARファイルを実行します。
bash
java -jar target/helloworld-1.0-SNAPSHOT.jar

この方法では、com.example.App のような完全修飾名をコマンドラインで指定する必要がなくなります。もし頻繁にJARファイルを実行するのであれば、maven-jar-pluginを設定してjava -jarコマンドを使う方が簡単で便利です。

Mavenのキャッシュ

Mavenを使って開発するとき、毎回ビルドするたびにすべての依存関係をダウンロードするわけではありません。以下の点を理解すると、Mavenの動作がより明確になります。

ローカルリポジトリのキャッシュ

Mavenは依存関係を一度ダウンロードすると、ローカルリポジトリ(通常、~/.m2/repository/に保存されます)にキャッシュします。そのため、同じ依存関係を持つ別のプロジェクトや、同じプロジェクトで再度ビルドする際には、既にダウンロードされた依存関係を再利用するため、再度ダウンロードされることはありません。

ビルド時間の短縮

  • インクリメンタルビルド: Mavenはソースコードやリソースの変更があった部分だけを再コンパイルする機能を持っており、すべてを一からビルドするわけではありません。これにより、ビルド時間が短縮されます。
  • キャッシュの再利用: 先述した通り、一度ダウンロードされた依存関係はキャッシュされるため、次回以降のビルド時に時間がかかりません。

依存関係の更新

Mavenはデフォルトでリリース済みの依存関係を更新しませんが、スナップショット版(開発中のバージョン)を利用している場合は、最新の依存関係を取得するためにリモートリポジトリを確認します。しかし、通常のリリース版を使用している場合は、必要がない限り再ダウンロードは行われません。

ビルドの高速化

  • Maven Wrapper: プロジェクトごとにMavenのバージョンを固定し、ビルドの再現性を保つためのツールです。これにより、異なる環境間でのビルド時間を均一に保てます。
  • 並列ビルド: 複数のモジュールを持つプロジェクトで、Mavenは並列ビルドをサポートしており、ビルド時間を短縮できます(-Tオプションを使用します)。

ビルドの最適化

  • オフラインモード: Mavenは-oオプションを使用することで、オフラインモードでビルドを実行できます。これにより、インターネットに接続せずにローカルキャッシュを利用してビルドするため、ネットワークアクセスによる遅延が発生しません。
  • インクリメンタルビルドツールの利用: JRebelSpring Boot DevToolsなどのツールを使うことで、特に開発中のフィードバックループを短縮し、ビルドとデプロイの待ち時間を減らすことができます。

Mavenのビルドプロセスは、依存関係を一度ダウンロードした後はキャッシュを利用するため、毎回ビルドするたびに依存関係をダウンロードするわけではなく、ビルド時間もそれほど問題になることは少ないです。ただし、プロジェクトの規模が大きくなるとビルド時間がかかることがあるため、上記の方法を活用してビルドの最適化を行うとよいでしょう。

関連記事

最後までご覧いただきありがとうございます!

▼ 記事に関するご質問やお仕事のご相談は以下よりお願いいたします。
お問い合わせフォーム