検証環境としての Tomcat9 インストール・フリー構築法 ～ 超簡単 ～

## はじめに

「ちょっとこれ試してみたいなぁ。」と思った時、いちいち環境構築をするのは面倒です。
バージョン違いの同一ソフトが既 PC 内に存在する時などは特に。。
なので、近年は VM や Docker などが一般化しつつあるのだろうなと思います。

ただ「VM は PC のパワーが要るし Docker はちょっと敷居が高い」という場合、インストール・フリーでポータブルな環境が手軽に作れると非常にありがたいです。
いわゆる「前回の検証」の影響を受けることなく、毎回初期化された環境が準備できるので。

Tomcat についても ZIP 版を利用すればインストール・レスで即座に複数バージョンの環境を準備できるので、「これまで `msi` 形式のインストーラしか使ったことない。」という人向けに備忘録も兼ねてまとめてみます。

:::note warn
前提条件として、Java11のインストールとセットアップは完了していることとします。

```cmd:Java11 がセットアップされていること（例）
C:\Users\xxx>java --version
openjdk 11.0.19 2023-04-18 LTS
OpenJDK Runtime Environment Zulu11.64+19-CA (build 11.0.19+7-LTS)
OpenJDK 64-Bit Server VM Zulu11.64+19-CA (build 11.0.19+7-LTS, mixed mode)
```

```cmd:JAVA_HOME が設定されていること
C:\Users\xxxx>echo %JAVA_HOME%
C:\Program Files\Zulu\zulu-11
```
:::

## 環境の準備

1. [公式サイト](https://tomcat.apache.org/download-90.cgi)から OS に合った ZIP をダウンロードします。    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/125919c0-12fe-39be-7e6b-24224d54ce6b.png)

1. ZIP を解凍し、任意の場所に配置します。（ `%userprofile%` 配下など）

    ```sh:解凍したフォルダの構造（概要）
    📁 apache-tomcat-9.0.x
     ├─ 📁 bin         # Tomcatを起動・停止するバッチファイルやスクリプトが格納されています。
     ├─ 📁 conf        # Tomcatの設定ファイルが格納されています。
     │  └─ 📁 Catalina
     │      └─ 📁 localhost
     ├─ 📁 lib         # Tomcatが必要とするライブラリやクラスが格納されています。
     ├─ 📁 logs        # Tomcatのログファイルが格納されています。
     ├─ 📁 temp        # Tomcatが一時的に使用するファイルが格納されています。
     ├─ 📁 webapps     # TomcatにデプロイするWebアプリケーションが格納されています。
     │  ├─ 📁 docs       # 各アプリケーションはサブフォルダに配置します。
     │  ├─ 📁 examples
     │  ├─ 📁 host-manager
     │  ├─ 📁 manager
     │  └─ 📁 ROOT
     └─ 📁 work       # TomcatがJSPをサーブレットに変換したファイルやクラスが格納されています。
         └─ 📁 Catalina
             └─ 📁 localhost
                 ├─ 📁 docs
                 ├─ 📁 examples
                 ├─ 📁 host-manager
                 ├─ 📁 manager
                 └─ 📁 ROOT
    ```

1. 以上で準備完了。:open_mouth:

## 展開した Tomcat の起動方法

### Case１：コンソールアプリとして実行

1. `bin` フォルダ内に `setenv.bat` というファイルを新規作成し、以下のように記載します。

    ```java:setenv.bat の記載内容
    # -Xms : ヒープサイズの初期値を設定するオプションです。
    # -Xmx ：ヒープサイズの最大値を設定するオプションです。
    # -Xss : スレッドごとのスタックサイズを設定するオプションです。
    set CATALINA_OPTS=-Xms512m -Xmx2048m -Xss256k -XX:+UseG1GC
    ``` 

1. `bin` フォルダ配下の `startup.bat` を実行する。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/d9aa604e-75f9-cf63-d2cd-127e237df505.png)
    コンソールが表示され、Tomcat サーバーが起動。
    Shift_JIS でコンソールを表示しており文字化けしてますが、log ファイルには UTF-8 で正常に出力されているので問題ありません。:open_mouth:
    <details><summary>logの画像</summary>        

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/db4d6475-b885-4ac3-573f-8f7fe1176655.png)
    </details>

1. `jps -v` コマンドを実行し `setenv.bat` で設定した環境変数が反映されていることを確認

    ```java:CATALINA_OPTSにセットした値を確認
    > jps -v
    8120 Bootstrap --add-opens=java.base/java.lang=ALL-UNNAMED ...
    .webresources -Xms512m -Xmx2048m -Xss256k -XX:+UseG1GC ...
    ```

1. コンソールを閉じるとサーバも停止します。
---

### Case２：Windows サービスとして実行

1. `bin` フォルダ配下の `service.bat` を実行する。
    
    ```powershell:例えば "TomcatForEvaluation" というサービス名で登録する場合
    .\service.bat install TomcatForEvaluation
    ```
    実行結果
    ```powershell:名前を付けてサービス登録した結果
    PS C:\xxx\apache-tomcat-9.0.74\bin> .\service.bat install TomcatForEvaluation
    Installing the service 'TomcatForEvaluation' ...
    Using CATALINA_HOME:    "C:\xxx\apache-tomcat-9.0.74"        
    Using CATALINA_BASE:    "C:\xxx\apache-tomcat-9.0.74"        
    Using JAVA_HOME:        "C:\Program Files\Zulu\zulu-11"
    Using JRE_HOME:         "C:\Program Files\Zulu\zulu-11"
    Using JVM:              "C:\Program Files\Zulu\zulu-11\bin\server\jvm.dll"
    The service 'TomcatForEvaluation' has been installed.
    ```
    結果に表示される文字列（フォルダパス）については実行する環境によって異なりますが、無事 `installed` が表示されると、以下の様に指定したサービス名を付与して Windows サービスに登録されます。[^5]
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/17db9661-e125-6580-e792-ad96cd9bc2bc.png "Apache Tomcat9.0 TomcatForEvaluation")
    
1.  `bin` フォルダ配下の `Tomcat9w.exe` を起動し、`Log On` タブから `Local System account` を選択します。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/5240ad5c-cc0f-a8a6-42f3-9c05bc9aa2fe.png)

1.  同じく `Java` タブから `Initial memory pool`、`Maximum memory pool`、`Thread stack size` を設定します。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/0d8a6b86-fd3d-99f9-901e-415d54ffe2ec.png)

1. `General` タブから `Start` ボタンをクリックして Tomcat サーバを起動。:open_mouth:
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/d4fb7cde-efec-dae8-099c-61fd9e7aa2f1.png)



[^5]: 登録した Windows サービスを解除するには、同様に `remove` オプションを付与します。

    ```powershell:名前を指定してサービス登録解除
    PS C:\xxx\apache-tomcat-9.0.74\bin> .\service.bat remove TomcatForEvaluation
    Removing the service 'TomcatForEvaluation' ...
    Using CATALINA_BASE:    "C:\xxx\apache-tomcat-9.0.74"
    The service 'TomcatForEvaluation' has been removed
    ```

## インストール・フリー な Tomcat を使った開発・検証

インストール版の Tomcat と同じで、conf フォルダ内のファイルを編集することでサーバの設定を変更できますし、webapps の直下に ManagementConsole.war[^1] を配置すれば自動展開され、Management Console の検証環境として利用することも可能です。[^2]

[^1]: 通常はファイル名を `mc.war` に変更して利用します。（文字列短縮のため）
[^2]: 実際に Management Console の環境を構築するためには、そのほか DB の設定などが必要になります。

JVM の設定についても `setenv.bat` や `Tomcat9w.exe` を利用することでインストール版と同様の設定が可能、と思ってます。

:::note 
**環境変数の値と影響**（Bing AIに聞いてみた：サイズが不足するとどうなる？）
* **-Xmx**: ヒープサイズの最大値が不足すると、**java.lang.OutOfMemoryError: Java heap space** というエラーが発生します。このエラーは、Java アプリがヒープにオブジェクトを割り当てることができなくなったことを示しています。このエラーが発生すると、アプリはクラッシュする可能性があります。
* **-Xms**: ヒープサイズの初期値が不足すると、**java.lang.OutOfMemoryError: GC overhead limit exceeded** というエラーが発生する可能性があります。このエラーは、ガベージコレクション(GC)によってメモリを解放できないことを示しています。このエラーが発生すると、アプリのパフォーマンスが低下する可能性があります。
* **-Xss**: スタックサイズが不足すると、**java.lang.StackOverflowError** というエラーが発生します。このエラーは、スタックにオブジェクトを割り当てることができなくなったことを示しています。このエラーが発生すると、アプリはクラッシュする可能性があります。
:::

## まとめ

仕事柄、複数バージョンの環境を切り替えて調査や検証をすることがあるので、いちいちアプリケーションをインストールするのも大変ですし、コストカットが求められる昨今、AWSでインスタンスを作ればいいという話でもありません。

何よりも環境の使いまわしは検証自体の前提が狂ってしまい好ましくありません。[^3]

[^3]:「検証したつもり、、」になってしまうこともある。

個人的には Docker が第一選択肢ですが、Linux に抵抗があるという意見もあれば、検証の前提として Windows の環境が必要なこともある[^4] ので、普段業務で使っている Windows PC で手軽に試せる方法としてまとめてみました。

[^4]: 社内の環境が Windows なので。

## 次の記事

https://qiita.com/ParakeetOnTheHead/items/ec3821d2bc1f9c905716

## その他

最近は壁打ちやドラフト作成の段階で ChatGPT と Bing AI を併用してたりします。
以下に Bing とのやり取りの一部を引用しておきます。

Q.
> 一般的な社内システムの環境を構築する場合の初期パラメータとしてはどの程度が標準ですか？-Xmx、-Xms、-Xss それぞれについて、増減が必要となる要因と、下記の条件において標準的なサイズ、そしてその根拠・計算方法について記述ください。
> 
> **社内システムの条件**
> - 利用ユーザ数：300人
> - 同時アクセス数：100セッション
> - アプリの特性：Tomcat9上に構築したWebシステムであり、主に内部のタイマーにより定期的に外部のプログラムを呼び出しに行く管理コンソール機能がメイン。また、外部のプログラムからは疎通を確認するために5秒に1回程度受信がある。外部のプログラムの数は100程度。

A.
> -Xmx、-Xms、-Xss は、それぞれ Java のヒープサイズの最大値、初期値、スタックサイズを指定するオプションです> ¹。ヒープサイズは、Java アプリが動的に確保するメモリの量を制限するもので、スタックサイズは、各スレッドが使用するメモリの量を制限するものです²。
> 
> 一般的な社内システムの環境を構築する場合の初期パラメータとしては、以下のような要因が考慮されます³⁴。
> - 利用ユーザ数や同時アクセス数によって、必要なヒープサイズやスタックサイズが変わります。多くのユーザーやアクセスがある場合は、それに応じてヒープサイズやスタックサイズを増やす必要があります。
> - アプリの特性によって、必要なヒープサイズやスタックサイズが変わります。外部のプログラムを呼び出したり、受信したりする場合は、それに応じてヒープサイズやスタックサイズを増やす必要があります。
> - システムのパフォーマンスや安定性によって、必要なヒープサイズやスタックサイズが変わります。メモリ不足やガベージコレクションの頻度が高い場合は、それに応じてヒープサイズやスタックサイズを増やす必要があります。
> 
> 下記の条件において標準的なサイズとしては、以下のような値が考えられます¹³⁴。
> - -Xmx: 2 GB
> - -Xms: 512 MB
> - -Xss: 256 KB
> 
> これらの値は、以下のように計算されます。
> - -Xmx: 同時アクセス数 (100) x 平均セッションサイズ (20 MB) = 2 GB
> - -Xms: -Xmx の 25% = 512 MB
> - -Xss: デフォルト値 = 256 KB
> 
> ただし、これらの値はあくまで目安であり、実際にはシステムの動作状況を確認しながら調整する必要があります³⁴。
> 
> ソース: Bing との会話 2023/5/13
> (1) Configuring Tomcat's Java Heap Size | Jaspersoft Community. https://community.jaspersoft.com/wiki/configuring-tomcats-java-heap-size.
> (2) Tomcatのメモリ利用状況を調査・分析するための参考情報 - Qiita. https://qiita.com/You_name_is_YU/items/f1155bccfc64bdd792c0.
> (3) Tomcat のヒープ サイズを増やす方法 - MicroStrategy. https://www.microstrategy.com/ja/support/support-videos/how-to-increase-the-heap-size-in-tomcat.
> (4) Tomcat構成の推奨事項 - Oracle. https://docs.oracle.com/cd/E48349_01/integrator.300/integrator_install/src/cli_ldi_server_config.html.