Mavenキホンのキ

◆ Live配信スケジュール ◆
サイオステクノロジーでは、Microsoft MVPの武井による「わかりみの深いシリーズ」など、定期的なLive配信を行っています。
⇒ 詳細スケジュールはこちらから
⇒ 見逃してしまった方はYoutubeチャンネルをご覧ください
【5/21開催】Azure OpenAI ServiceによるRAG実装ガイドを公開しました
生成AIを活用したユースケースで最も一番熱いと言われているRAGの実装ガイドを公開しました。そのガイドの紹介をおこなうイベントです!!
https://tech-lab.connpass.com/event/315703/

こんにちは、サイオステクノロジー武井です。今回は、Mavenについて書こうとおもっております。でもMavenの細かい話は抜きにして、なんでそんなもん必要なのっていうところに重点を置いて、書きたいと思います。

gradleとかもありますが、未だにまだMavenって現役ですよね?っておもっていますので、きっとこの記事が誰かの役に立つと思います。

Mavenって?

Javaのソースコードのコンパイルやビルドの手順を簡単にしてくれて、さらにライブラリの依存性を解決した上で、中央集権的に管理されたリポジトリからライブラリを簡単に取得出来るツールです。

Mavenを使わないとどうなるか?

先の説明では、少々、というか全然わからないと思います。私も初めてMavenを学んだときは、Mavenの使い方が書いてある本や記事はあったのですが、そもそもその必要性がよくわかりませんでした。そこから説明してほしかったなーと思います。

ということで、まずはMavenを使わないでいろんなことをしてみたいと思います。

簡単なハロワを実行

まずは簡単なハロワ(Hello Worldと表示するプログラム)を作ってみます。

今回作成するハロワのディレクトリ構成とファイル群は下記のとおりです。

com
└── example
    └── demo
        ├── HelloWorld.java
        └── Person.java

 

上記のソースコードの詳細は以下の通りです。

package com.example.demo;

// 人を表すクラス
public class Person {

  // 人の名前
  private String name;

  // コンストラクタで人の名前を渡す
  public Person(String name) {
    this.name = name;
  }

  // 名前を取得するメソッドを定義する
  public String getName() {
    return this.name;
  }
}
package com.example.demo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
  public static void main(String[] args) {
    // Personクラスからインスタンスを生成し、その際コンストラクタの引数で名前を渡す
    Person person = new Person("ntakei");

    // 「Hello World!![人の名前]」と表示する。
    System.out.println("Hello World!! " + person.getName());
  }
}

 

これを実行するためには、コンパイルが必要です。ということでコンパイルします。Person.classとHelloWorld.classの2つのファイルが出来上がります。

$ javac com/example/demo/HelloWorld.java

 

実行します。

$ java com/example/demo/HelloWorld
Hello World!! ntakei

 

手順をまとめると以下のような感じです。

  1. コンパイルする。
  2. 実行する

なかなかにめんどくさいですね。

簡単なハロワをjarにする

さて、先のハロワですが、他の環境で実行したいときに、わざわざPerson.classとHelloWorld.classの2つのファイルを持ち歩くのは面倒です。そこで、Javaにはjarという仕組みがあって、複数のクラスやその実行に必要な設定ファイルなどを一つのファイルにすることが出来ます。

ということで先程のハロワをコンパイルからやり直してみましょう。ということでコンパイルします。Person.classとHelloWorld.classの2つのファイルが出来上がります。

$ javac com/example/demo/HelloWorld.java

 

jarにします。tarコマンドとインターフェースが非常に似ています。同じディレクトリにhelloworld.jarというファイルが出来上がっているはずです。

$ jar cvf helloworld.jar .
$ ls
com helloworld.jar

 

jarからプログラムを実行してみましょう。

$ java -cp helloworld.jar com.example.demo.HelloWorld
Hello World!! ntakei

 

手順をまとめると以下のような感じです。

  1. コンパイルする
  2. jarにする
  3. 実行する

だんだん手順が増えてめんどくさくなりました。つらみー。

ログを出力出来るようにする

ハロワに簡単なログを出力出来るようにしましょう。そのためにはslf4jライブラリが必要になります。https://www.slf4j.org/のサイトから以下の2つをダウンロードします(バージョンは2021年6月21日時点での最新です)。

  • slf4j-api-1.7.9.jar
  • slf4j-simple-1.7.30.jar

そしてそのライブラリを以下のように配置します。

com
└── example
    └── demo
        ├── HelloWorld.java
        └── Person.java
slf4j-api-1.7.9.jar
slf4j-simple-1.7.30.jar

 

HelloWorld.javaを以下のように修正します。

package com.example.demo;

// slf4jのライブラリをインポートする
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
  public static void main(String[] args) {
    // ログ出力のための準備をする
    Logger logger = LoggerFactory.getLogger("testlogger");

    // ログ出力!!
    logger.info("hogefugapiyo");
    Person person = new Person("ntakei");
    System.out.println("Hello World!! " + person.getName());
  }
}

 

コンパイルします。先程のslf4jライブラリを指定する必要があります。

$ javac -cp .:slf4j-api-1.7.9.jar:slf4j-simple-1.7.30.jar com/example/demo/HelloWorld.java

 

jarにします。

$ jar cvf helloworld.jar .

 

実行します。

$ java -cp helloworld.jar:slf4j-api-1.7.9.jar:slf4j-simple-1.7.30.jar com/example/demo/HelloWorld
[main] INFO logger - hogefugapiyo
Hello World!! ntakei

 

手順をまとめると以下のような感じです。

  1. ライブラリをダウンロードする。
  2. コンパイルする
  3. jarにする
  4. 実行する

もうつらい。

Mavenを使うとどうなるか?

ヽ(=´▽`=)ノ

Mavenは、今までMavenを使わない場合に実行してきた「ライブラリをダウンロードする」「コンパイルする」「jarにする」あたりを全部勝手にやってくれます。そういうツールなのです。ただし、Mavenの色々なお作法に従う必要があります。

お作法その1としては、ディレクトリ構成です。ということで、先に実行したハロワログ出力jar実行バージョンをMavenのお作法に合わせた構成にすると以下のようになります。

.
├── pom.xml → Mavenの挙動を定義したファイルです。
└── src
    ├── main
    │   └── java → ソースコードを格納するディレクトリです。
    │       └── com
    │           └── example
    │               └── demo
    │                   ├── HelloWorld.java
    │                   └── Person.java
    └── test
        └── java → テストコードを格納するディレクトリです。今回は使いません。
            └── com
                └── example
                    └── demo
                        └── AppTest.java

 

お作法その2としてはpom.xmlを書かなければいけないこととその書き方です。詳細は書籍とかを参照していただくとして、本記事ではその概要を説明します。

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <!-- このハロワのプログラムのグループID(会社名など)とアーティファクトID(プログラムの一意の名称)を定義する -->
  <groupId>com.example</groupId>
  <artifactId>HelloWorld</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>HelloWorld</name>

  <!-- Javaのコンパイル時のバージョンなどを定義する --> 
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <!-- 利用するライブラリを定義する。ここで定義すると勝手にMavenのリポジトリからダウンロードしてきてくれる -->
  <dependencies>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
      <version>1.7.30</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.30</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <!-- jarの作り方などを定義する -->
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>3.3.0</version>
        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

 

ではライブラリのダウンロード、コンパイル、jarの作成までやってみます。

$ mvn clean package

 

すると、targetディレクトリ配下に以下のファイルが出来ていると思います。これらの中のHelloWorld-1.0-SNAPSHOT-jar-with-dependencies.jarというのが成果物です。

$ ls target/
HelloWorld-1.0-SNAPSHOT-jar-with-dependencies.jar generated-sources surefire-reports
HelloWorld-1.0-SNAPSHOT.jar generated-test-sources test-classes
archive-tmp maven-archiver
classes maven-status

 

実行してみましょう。

$ java -cp target/HelloWorld-1.0-SNAPSHOT-jar-with-dependencies.jar com.example.demo.HelloWorld 
[main] INFO testlogger - hogefugapiyo
Hello World!! ntakei

あら、これだけ?

以下の手順になりました。あの複雑だった手順がマジシンプルに!!

  1. mavenでビルドする。
  2. 実行する。

まとめ

Mavenのお作法に従ったディレクトリ構成にソースを置いて、pom.xmlを定義するだけで、ビルドやライブラリのダウンロードなど面倒なことを全てやってくれるのです。とっても便利ですね。

アバター画像
About 武井 宜行 269 Articles
Microsoft MVP for Azure🌟「最新の技術を楽しくわかりやすく」をモットーにブログtech-lab.sios.jp)で情報を発信🎤得意分野はAzureによるクラウドネイティブな開発(Javaなど)💻「世界一わかりみの深いクラウドネイティブ on Azure」の動画を配信中📹 https://t.co/OMaJYb3pRN
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる