【初心者向け】Apache TomcatへのWARファイルのデプロイ手順（ざっくり）


<!--

## 技術記事のタイトル

最も伝えたいこと。
簡潔かつ分かりやすく過不足ないタイトルを考えましょう。

### 【 】(墨付き括弧)

- 【言語やサービス】
    - 例1.【Python】すぐにpytestで単体テストを実行するまでの手順
- 【言いたいこと】
    - 例1.【必見】Objectはどこに消えた？
- 【前提】
    - 例1.【個人開発】○○を○○できるサービスをリリースしました
    - 例2.【初心者向け】Reactとはそもそも何なのか説明します
- 【続き物の番号】
    - 例1.【2024年版】新入社員向け研修資料を公開します
    - 例2.【環境構築編】Windows11でPythonを実行するまで

【前提】詳しいタイトル【言語やサービス】のように、複数を併用するパターンもあります。

-->

## はじめに
<!--
何についての記事なのか、誰に向けた記事なのかを簡単に説明しましょう。
-->

### この記事でわかる・できること
<!--
読んだら何がわかるようになるのか、何ができるようになるのかを書きましょう。
-->

- JavaプログラムからWARファイルを作成する方法
- Tomcatの導入方法
- TomcatへWARファイルをデプロイする方法

### 前提
- Javaプログラムが作成済みであること

### この記事の対象者
<!--
誰に向けた記事なのかを明確にすることで読者に選んでもらいましょう。
-->

- 初めてTomcatにアプリをデプロイするよ～という方
- WARファイルの作成が上手くいかないよ～という方

などなど

### 動作環境・使用するツールや言語
<!--
誰に向けた記事なのかを明確にすることで読者に選んでもらいましょう。
環境を書くと分かりやすいです。
- OS バージョン
    - 例 Windows11 23H2
- ツール
    - 例 VSCode 1.86.2
- 言語
    - 例 Python 3.12.2
- フレームワーク
    - 例 flask 3.0.2
-->

- OS バージョン
    - ゲストOS：Ubuntu 24.04.2 LTS
    ※WSL2上で動かしています
    - ホストOS：Windows11 Home 24H2
- ツール バージョン
    - Visual Studio Code Version 1.99.0 (user setup)
    - Apache Maven 3.8.7
        - Java version: 21.0.6
        - vendor: Ubuntu
        - runtime: /usr/lib/jvm/java-21-openjdk-amd64
    - Apache Tomcat/9.0.104
        - OS Name:        Linux
        - OS Version:     5.15.167.4-microsoft-standard-WSL2
        - Architecture:   amd64
        - JVM Version:    21.0.6+7-Ubuntu-124.04.1
        - JVM Vendor:     Ubuntu
- 言語 バージョン
    - Java openjdk 21.0.6 2025-01-21

## やってみたこと
<!--
章全体の要約や、何について書くのかをここに書きます。
記事が長い時や資料として作るときは番号を振ることをおすすめします。
章を増やすときは章から項までをコピーしてください。
-->
手元にJavaプログラムがある状態から、WARファイルを作成してApache Tomcat（以下、Tomcatと呼びます）をインストールし、デプロイしてみました。
4時間くらいCopilot君やChatGPT君と相談してようやくできたので、備忘も兼ねてざっくり手順を共有します。

## 手順１　JavaプログラムからWARファイルを作成
まず前提として以下の4つを示します。
- カレントディレクトリ
- カレントディレクトリからのディレクトリ構造（ツリー形式）
- Javaソースファイルの内容
- pom.xmlファイルの内容

```bash:カレントディレクトリ
###コマンド
pwd

###実行結果
/home/shigemasa89/nogizaka46-playlist-maker/demo
```

```bash:カレントディレクトリからのディレクトリ構造
###コマンド
tree

###実行結果
.
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── ScrapeSongTitlesServlet.java
    │   └── resources
    └── test
        └── java

9 directories, 2 files
```

```java:ScrapeSongTitlesServlet.java
package com.example;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ScrapeSongTitlesServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.setContentType("text/html; charset=UTF-8");
        StringBuilder html = new StringBuilder("<html><body><h1>乃木坂46の楽曲一覧</h1><ul>");

        try {
            String url = "https://n46db.com/songs/all-songs-list.php";
            Document doc = Jsoup.connect(url).get();
            Element songTable = doc.selectFirst("table:nth-of-type(3)");
            Elements songRows = songTable.select("tbody tr");

            for (Element row : songRows) {
                Element songTitleCell = row.selectFirst("td:nth-of-type(2)");
                if (songTitleCell != null) {
                    html.append("<li>").append(songTitleCell.text()).append("</li>");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            html.append("<li>データ取得に失敗しました。</li>");
        }

        html.append("</ul></body></html>");
        resp.getWriter().write(html.toString());
    }
}
```

```xml:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>1.0</version>
    <packaging>war</packaging><!-- warファイルとしてパッケージング -->

    <properties>
        <maven.compiler.source>21</maven.compiler.source><!-- 使用中のJavaバージョンを指定 -->
        <maven.compiler.target>21</maven.compiler.target><!-- 使用中のJavaバージョンを指定 -->
    </properties>

    <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
    <dependencies>
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.19.1</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.1</version>  <!-- 最新バージョンに更新 -->
            </plugin>
        </plugins>
    </build>
</project>
```

カレントディレクトリにpom.xmlファイルが配置されていることを確認し、以下のコマンドでWARファイルを作成します。
※WARファイルにするという情報はpom.xmlファイルに記述してあります。
```bash:WARファイル作成
    mvn package
```
このコマンドによって、カレントディレクトリからのディレクトリ構造（ツリー形式）は以下のようになりました。
欲しかったWARファイル「target/demo-1.0.war」が作成されていますね。

```bash:カレントディレクトリからのディレクトリ構造
###コマンド
tree

###実行結果
.
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── example
│   │   │           └── ScrapeSongTitlesServlet.java
│   │   └── resources
│   └── test
│       └── java
└── target
    ├── classes
    │   └── com
    │       └── example
    │           └── ScrapeSongTitlesServlet.class
    ├── demo-1.0
    │   ├── META-INF
    │   └── WEB-INF
    │       ├── classes
    │       │   └── com
    │       │       └── example
    │       │           └── ScrapeSongTitlesServlet.class
    │       └── lib
    │           └── jsoup-1.19.1.jar
    ├── demo-1.0.war
    ├── generated-sources
    │   └── annotations
    ├── maven-archiver
    │   └── pom.properties
    └── maven-status
        └── maven-compiler-plugin
            ├── compile
            │   └── default-compile
            │       ├── createdFiles.lst
            │       └── inputFiles.lst
            └── testCompile
                └── default-testCompile
                    └── inputFiles.lst

29 directories, 10 files
```

## 手順２　Tomcatをインストールして起動確認
### 1. Tomcatのtarを持ってくる

以下のページで、安定していそうなものとしてTomcat 9.0.104（9.0.xの中の最新版）を選択しました。
https://tomcat.apache.org/whichversion.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719939/76f1d028-6266-456f-b0a1-805b9d6b3541.png)

そしてTomcat 9のダウンロードページを選択し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719939/02e223f7-1bbf-49fa-ae32-5f0cad60c8a3.png)

https://tomcat.apache.org/download-90.cgi

tar.gzのリンクを右クリックしてリンクのアドレスをコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719939/b93a6dc9-9c61-479a-9f3b-c964c36a922d.png)

カレントディレクトリ上で、コピーしたアドレスを使って以下のコマンドを実行し、tomcatのtar.gzをダウンロードします。
```bash:tar.gzのダウンロード
wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.104/bin/apache-tomcat-9.0.104.tar.gz
```

### 2. tar.gzファイルを解凍
続いて以下のコマンドを実行してtar.gzファイルを解凍します。
```bash:tar.gzのダウンロード
tar -xzvf apache-tomcat-9.0.104.tar.gz
```

### 3. 起動確認
Tomcatのbinディレクトリの中から以下の「startup.sh」を見つけます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719939/e98787c6-828a-466c-bae3-a34d06d55e56.png)

以下の、カレントディレクトリからの「startup.sh」の相対パスを貼り付けたコマンドでTomcat君を起動できます。
```bash:Tomcatの起動
apache-tomcat-9.0.104/bin/startup.sh
```

以下にアクセスしてみましょう。
http://localhost:8080/

こんな感じでTomcatのページが表示されれば正常に起動されています！
**パーティーをしましょう！**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719939/c067ff36-d73b-4017-9fba-6d9c881d9285.png)

## 手順３　WARファイルをTomcatにデプロイ
さあ、いよいよ手順１で作ったWARファイルをTomcatにデプロイしましょう。
アプリの動作を見るのが楽しみですね。

以下のコマンドで、手順１で作ったWARファイルをTomcatのwebappsディレクトリにコピーします。
```bash:Tomcatの起動
cp target/demo-1.0.war apache-tomcat-9.0.104/webapps
```

すると以下のようにwebapps配下に「demo-1.0」ディレクトリが自動作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719939/ca2e2f06-3cca-453b-9b85-22fa84002422.png)

この中のWEB-INFディレクトリに以下のような内容で「web.xml」ファイルを作成します。
```xml:web.xml
<web-app>
    <servlet>
        <servlet-name>ScrapeSongTitlesServlet</servlet-name>
        <servlet-class>com.example.ScrapeSongTitlesServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ScrapeSongTitlesServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
```

そして、以下のURL（localhost:8080/{WARファイルデプロイで自動作成されたディレクトリ名}/）にアクセスします。
http://localhost:8080/demo-1.0/

アプリが正常にデプロイされていれば、以下のようにJavaプログラムが起動されていると思います！
お疲れ様でした！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719939/53f9bd6a-66e9-47ef-934f-f10b4e13cc47.png)

## おわりに・まとめ
今回は自分でWebアプリを作ってみたいなと思い、手始めにTomcatをインストールして簡単なアプリをデプロイしてみました。
今後も、気が向いたらまた投稿するかもしれないので、そのときはよろしくお願いします。

楽しみながら開発を続けていけたらなと思っています！
この度は最後までお読みいただき、ありがとうございました！