IntelliJ CommunityでTomcat, Context, デバッグ設定

# はじめに
優れた環境は、開発の効率をあげてくれます.

もともとは Eclipse ユーザーでして、クラスパスだの Tomcat 設定だの、そのあたりは Eclipse が全部やってくれましたが、サクサクと動く IntelliJ に出会ってからは、あのサクサク感が捨てきれず、乗り換えることになりました.
とはいえ、IntelliJ の場合 Eclipse 並みの「便利さ」を得るためには、IntelliJ IDEA Ultimate(有償版)を買う必要があります. お金の力です.

私は今のところ IntelliJ Community(無償版)主義で、理由は以下の通りです.
・ 有償版ライセンスに月々投資する金額で、書籍と講座、デバイスやハードウェアの部品などを購入したい
・ ある程度の基底のところは自分で設定したい

後者に関しては、たまに IDE を使わないで vim と javac コマンドでパッケージを一つ作成しようとなる、あの感覚に似ているかもしれません.

# ゴール
IntelliJ Community でざっくりと Tomcat とデバッガの設定をすること.
① sample-app という名のアプリで ② DB リソースはローカルの MySQL を使い ③ ```http://localhost:8080/sample-app/``` に接続できるようにしてみます.

OS は　mac です.

### 省略
Tomcat を 繋ぐだけなので java サーブレットや jsp、Spring frame の初期設定に関わる
0. ```javax.servlet```
1. ```pom.xml```
2. ```web.xml(の bean 設定)```
3. ```${servlet-name}-servlet.xml``` (または```application-context.xml```)
4. ```servlet.xml``` における component-scan、annotation-driven、View Resolver、静的ファイルのマッピング などの設定

などなどは省略して、DB 設定周りとデバッグをメインに整理したいと思います.

# IntelliJ で web アプリ用のパッケージを作る

### まず
apache tomcat は<a href='http://tomcat.apache.org/'>公式ホーム</a>で必要なバージョンを選びインストールします.

たまに、既存の tomcat と java の最新バージョンが合わない問題がありますが、例えば少し古い Tomcat のまま、java8 と java9 を入れていて、
環境変数設定で9にアップグレードされていた JAVA_HOME を8に下げることで解決できたり.

### File -> new -> Project...
![1.png](https://qiita-image-store.s3.amazonaws.com/0/194231/17ba4afc-dd1f-32cf-3b61-16848b8ee127.png)

maven 使いたいので maven の webapp にします.

### 何か入力して Next, Next, Next..
![s1.png](https://qiita-image-store.s3.amazonaws.com/0/194231/88ad9afc-1d37-9741-700e-353cf55d13a5.png)

たまたま被せましたが、別にアプリケーション名じゃなくてかまいません.

<a href='https://maven.apache.org/pom.html'>Maven POM Reference</a> によると

* GroupId<br>This is generally unique amongst an organization or a project.
* ArtifactId<br>The name that the project is known by.

要するに、groupId には他のプロジェクトと区別できる機関名などを含む名前が指定できるもので、artifactId にはプロジェクトの名前を決めて入れるのだと思います.

個人開発なら、そんなにこだわらなくて良いと言われた覚えが、ある.


### pom をライブラリに読み込んでみよう

まだ pom が読まれていない、かつ、デプロイする準備もできていない最初の状態から、pom だけ読み込みます.
デフォルトで JUnit が記述されているうと思いますが、これだけだとアプリ開発できません.

![s2.png](https://qiita-image-store.s3.amazonaws.com/0/194231/de0a7a9d-f365-1b23-11d3-a9cab6a6aad4.png)

すでに試しで、java-servlet を追加して入れて reimport しています.
External Libraries に java-servlet も追加され、参照できるようになりました.


### デプロイ
.java ファイルを実行可能な .class ファイルに変換します.

![s3.png](https://qiita-image-store.s3.amazonaws.com/0/194231/72199f97-0723-44ed-258d-1dacf60ad201.png)

開発中は一度 clean してから行いますが、まだ何もないので package を押して実行可能な target package を生成します.
名前が target なのは確かデフォルト名だった気が.

![s4.png](https://qiita-image-store.s3.amazonaws.com/0/194231/f1df1a01-a268-7803-7074-c526531e64c1.png)

できました. 
File -> Project Structure -> complier output 設定と似たようなものです.

電球マークが、Ultimate 版いいよと言っていますね 笑.. 

#### めんどくさいのは Run -> Edit Configuratons... にやらせます.

まったく同じ話ですが、左上の ＋ を押して Maven を追加、引数のコマンドとして、clean と package を同時に行えるコマンドをあらかじめ渡しておきます.

![s5.png](https://qiita-image-store.s3.amazonaws.com/0/194231/ee95bf73-e295-b353-7969-549cbcc1d75e.png)

Working directory ですが、アプリケーションのディレクトリの絶対パスじゃないとだめでした. 私の場合、mac のホームディレクトリに入れているのでああいう書き方をしています. また、sample-config という Name は適当です. 

-Dmaven.test.skip=true に関しては、デプロイの時間短縮をしたい時、テストを省略するオプションです. テスト省略は本来は推奨されないみたいですが、ファイルが増えることによりデプロイ作業自体が重たくなるので、よく使っています.

![s6.png](https://qiita-image-store.s3.amazonaws.com/0/194231/bbf85482-56e0-213d-ddaa-fcbf0db49fc6.png)

と、こういうのが追加されました. ワンクリックでこれからは楽々進められます.

#### コマンドラインが一番楽だったり

mvn コマンドを公式ホームなどで入手しインストールして、

```
$ cd {$APP_HOME}
$ mvn clean package -Dmaven.test.skip=true
```

を打つのも便利です.


# Context と Resource (データベース)の設定
```{$CATALINA_HOME}/conf/Catalina/${HOST_NAME}/```
直下に ```${APP_NAME}.xml``` ファイルを作ります. 

```{$CATALINA_HOME}``` は 各自の apache-tomcat の場所で、```${HOST_NAME}```は、ローカルなら ```localhost``` で大丈夫です.
```${APP_NAME}.xml``` ですが、今回作るアプリケーションには sample-app という名前をつけたので、絶対パスで表すと、

```/私のTomcat/conf/Catalina/localhost/sample-app.xml``` になります.

## 一つのTomcat に複数のアプリを入れる場合は、コンテキストごとに設定ファイルを作る
```{$CATALINA_HOME}/conf/``` 直下にも```Server.xml```があり、直書きしても動きはしますが、
これは全アプリケーション共通設定なので、DBコネクションなど個々のアプリごと設定を指定したい場合は、conf 直下の Server.xml には手を触れず、```{$CATALINA_HOME}/conf/Catalina/${HOST_NAME}/```直下にココンテキスト(アプリケーション)ごと設定ファイルを作ってあげた方がいいと思います.

たとえば、こうして DB Connection(MySQL) の設定を Resource に書いて保存します.

```sample-app.xml
<Context docBase="{$APP_HOME}/target/sample-app" path="/sample-app" reloadable="true">

  <Resource 
    name="jdbc/${jdbc_NAME}"
    type="javax.sql.DataSource"
    auth="Container"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://${DB_SERVER}/＄{DB_NAME}?userUnicode=true&amp;charactorEncoding=UTF-8&amp;autoReconnect=true"
    username="${USER}" password="${PASS}" 
    validationQuery="select CURRENT_TIMESTAMP"
  />

</Context>
```
## Context - アプリケーション構成情報

* <b>docBase</b> <br> アプリケーションを配置した場所. <br>.java ファイルではなく、コンパイルを経て実際動いてくれる <b>.class ファイルが生成され保存される場所</b>.
>
```{$APP_HOME}```はアプリの開発を行なっているディレクトリーの絶対パスです.
直下の```{$APP_HOME}/target/sample-app}```ですが、IntelliJ で設定した、デプロイをする度にクラスファイルが排出される場所です. 
私は```/target/${APP_NAME}```にしました. クラスファイルが保存される場所をきちんと決めて指定できれば、名前はなんだっていいと思います.
標準は /webapp からの相対パスですが、今回は絶対パスで指定しました.

* <b>path</b> <br> コンテキストのパスです. デフォルトは docBase 属性の値なので、今回のように docBase 属性の値同様 sample-app にする場合は省略可能なはず...
* <b>reloadable</b> <br> .class や .jar ファイルに更新がある場合、Tomcat がそれらを自動でリロードするかをチェックするかどうかを決めるフラグです. 開発中は true にしていますが、開発が全て終わった段階では false に書き換えた方がパフォーマンス的にいいと思います.

## Resource - DBコネクションを設定

利用するデータベースの数分、```<Resource>...</Resource>``` を追加します.

* <b>driverClassName</b><br> JDBC ドライバの完全修飾クラス名です.
* <b>type</b> <br>リソースの型です. データソースを使う場合、```javax.sql.DataSource```と指定します.
* <b>auth</b><br> リソースの制御方式です. データソースを使う場合、```Container```と指定します.
* <b>name</b><br> データソースにつける名前です.

>* Spring Framework における jndi (Java Naming and Directory Interface) とサーブレット設定例<br>
オブジェクトに名前をつけてあげる（バインディングする)ようなもの.<br>
```web.xml``` の ```<servlet-mapping>``` で指定した ```<servlet-name>``` が sampleApp だとしたら、このような名称で設定ファイルを書くと思います. ```application-context.xml``` を利用し設定することもあります.

>```sampleApp-servlet.xml
<!-- DB Connection -->
<bean id="sampleDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="java:comp/env/jdbc/${jdbc_NAME}"/>
</bean>
```
> ```bean id``` は、DataSource の名前を指定しました. のちにトランザクション処理を追加する時など、```<property name="dataSource" ref="sampleDataSource"/>``` のように ```ref``` のところに使われます.

> 先ほどの ```Resource``` に ```name="jdbc/sampleDB"``` と入れたなら、```java:comp/env/jdbc/sampleDB``` になると思います.

* <b>url</b> <br> サーバも DB サーバもローカルで、 MySQL の sample_DB という DB に接続したい場合は、```jdbc:mysql://localhost/sample_DB``` などになります.<br>外部 DB サーバ を利用する場合はそのサーバの接続情報を入力します.<br>後ろの ? パラメータとしてつけているのは、エンコードとか、MySQL のコネクションを持続させるための任意のオプションです. 
* <b>username と password</b> <br> MySQL ログイン時に使っている name と password を入れます.
* <b>validationQuery</b> <br> 長時間接続がない場合、コネクションプールからコネクションを取得する際に、コネクションが生きているかどうか確認するための、任意の低負荷のクエリーです.


これは、全属性を網羅しているわけではなく...例えば、
外部 DB ではなく、ローカル上のリソースを個人利用すると想定し、コネクションプールのアイドル設定の <b>maxIdle</b> や
 プールの最大コネクション数の <b>maxActive</b> などは省きました.

>* コネクションプール
ここでのプールは、保持するという意味を持っています. コネクションプールは、アプリケーションと DB サーバの間で、複数のコネクションを保持できます.
コネクションを再利用し、データベースの接続状態を管理する機能です. クローズ(解放)は、次のコネクションのために使い終わったコネクションをプールに返却するための処理です.

>* idle(アイドル)
プールしておいた(確保しておいた) コネクションです.


# Tomcat 起動

```
$ cd ${apache-tomcat の場所}/bin
$ sh startup.sh
```

終了時は

```
$ sh shutdown.sh
```

たまに、あやまって二重起動しちゃったり、でプロセスが残ったりするので、その際は

```
$ ps -ef | grep tomcat
```

して、適切な番号を ```kill``` してあげたり.

# ブラウザで確認
![s7.png](https://qiita-image-store.s3.amazonaws.com/0/194231/8a5c466e-f007-67cd-ad02-9160339aa053.png)

表示されている内容は、こちらのデフォルトで提供される jsp です.
target の方です.

![s8.png](https://qiita-image-store.s3.amazonaws.com/0/194231/935a78ee-77cc-fbfe-1d83-4924f81b6b6c.png)

ためしで target/sample-app/index.jsp を消してみると、ページが見つからない 404 になることがわかります.
もう一度デプロイすればまたできます.


# デバッガの設定
### bin/setenv.sh
さきほどの　apache-tomcatのデェレクトリ直下の bin ディレクトリの直下に
setenv.sh を作成します.

```
$ cd ${apache-tomcat の場所}/bin
$ vi setenv.sh
```

内容は以下の通りです.

```
export JPDA_ADDRESS=9999
export JPDA_TRANSPORT=dt_socket
```

9999 に意味はありません、割り当てられていなさそうなポート番号だから...
デプロイや実行は 8080ポート、リモートデバッグは 9999ポート で実現しているようなものです.

### Run -> Edit Configurations...
![スクリーンショット 2018-02-08 2.58.41.png](https://qiita-image-store.s3.amazonaws.com/0/194231/35843a64-ac08-3645-7743-b159143c53d0.png)

### Port 番号だけ 9999 に変える
![s9.png](https://qiita-image-store.s3.amazonaws.com/0/194231/4764b57f-6e5a-61ab-eff1-97c1eb3cb3d2.png)

### Tomcat を jpda オプションで起動
```
$ cd ${apache-tomcat の場所}/bin
$ sh catalina.sh jpda start 
```

オプション付き起動なので、```$sh startup.sh``` はしなくて大丈夫です.

### 設定してデバッガがセットされていることを確認
![s10.png](https://qiita-image-store.s3.amazonaws.com/0/194231/90726342-51db-9c96-426c-6eeacb3585e4.png)

いつも通りにブレークポイントを貼って、虫さんをぽちっとおせば、大丈夫です.



# おわりまして
初期設定は、毎日のようにやっているわけではないため、いざとなった時苦労することがあったので、自分メモを兼ね記述しました.

環境構築も、自分にあうやり方が一番いいと思います.
そのためには、有償版含めいろいろ試すのが第一かもですね.


以上

### 修正ログ
サンプルの名称をわかりやすく全て`sample`に統一しました.