java.net.ConnectException: ポート 1527 のサーバー localhost への接続中に…

## 概要
GrassFishでJPAのEntityManagerをインジェクションしようとすると、デプロイ時にエラーでハマったのでメモ

## 環境

| key | value |
|:---|:---:|
| OS | Windows10 |
| IDE | IntelliJ IDEA Ultimate |
| JDK | JDK8 |
| JavaEEサーバ | GrassFish5.0 |
| JPAプロバイダ | EclipseLink |
| ビルドツール | Maven |
| DB | MySQL5.7 |

## 事象
JAX-RSとJPAでRESTful APIを作っていたら、実行(WARのデプロイ時)にエラー

```shell
[2019-09-20 04:25:26,873] Artifact rest:war: Error during artifact deployment. See server log for details.
```

サーバログで詳細を確認しろとのこと

```shell:GrassFishLog
[2019-09-20T16:28:08.474+0900] [glassfish 5.0] [SEVERE] [] [javax.enterprise.system.core] [tid: _ThreadID=54 _ThreadName=admin-listener(5)] [timeMillis: 1568964488474] [levelValue: 1000] [[
  Exception while deploying the app [rest] : Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Error in allocating a connection. Cause: Connection could not be allocated because: java.net.ConnectException: ポート1,527のサーバーlocalhostへの接続中にメッセージConnection refused: connectでエラーが発生しました。
Error Code: 0]]
```
なにやらSQLの接続でエラーが発生しているが、デプロイ時にSQL？ポート1527？で混乱

## 状態

```java:ArticleResource.java
package com.example.resource;

import com.example.entity.ArticleEntity;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/article")
public class ArticleResource2 {

    // アノテーションでインジェクションしようとするとエラー
    @PersistenceContext(unitName = "NewPersistenceUnit")
    EntityManager em;

    @GET
    @Path("/{articleId}")
    @Produces(MediaType.APPLICATION_JSON)
    public ArticleEntity getArticle(@PathParam("articleId") int articleId) {
        // ここでnewすればエラーは発生しない
        // EntityManager em = Persistence.createEntityManagerFactory("NewPersistenceUnit").createEntityManager();
        ArticleEntity article = em.find(ArticleEntity.class, articleId);
        return article;
    }
}

```

```xml:persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">

    <persistence-unit name="NewPersistenceUnit">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>com.example.entity.ArticleEntity</class>
        <properties>
            <property name="eclipselink.jdbc.url" value="jdbc:mysql://localhost:3306?serverTimezone=Asia/Tokyo"/>
            <property name="eclipselink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="eclipselink.jdbc.user" value="xxx"/>
            <property name="eclipselink.jdbc.password" value="xxx"/>
        </properties>
    </persistence-unit>
</persistence>
```

## 対応

### 1. GrassFishにJDBCドライバを配置

- 配置場所: `C:\Users\<GrassFishのインストールフォルダ>\glassfish\domains\domain1\lib\ext`
- JDBCドライバ: `mysql-connector-java-8.0.15.jar`

### 2. GrassFishの管理コンソールからJDBC接続プールとJDBCリソースを作成

#### 設定内容

**＜JDBC接続プール＞**

- Pool Name: mysqlPool
- Resource Type: javax.sql.DataSource
- Datasource Classname: com.mysql.cj.jdbc.MysqlDataSource  **←mysql-connectorが5系の場合と異なるので注意**
- Additional Properties:  
    　serverName: localhost  
    　serverTimezone: Asia/Tokyo **←タイムゾーンの指定がないとエラーになったので追加**  
    　databaseName: blog  
    　user: xxx  
    　password: xxx  

**＜JDBCリソース＞**

- JNDI Name: jdbc/mysql
- Pool Name: mysqlPool

### 3. persisitence.xmlに設定を追加

```xml:persistence.xml(修正後)
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">

    <persistence-unit name="NewPersistenceUnit">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <!-- JTAデータソースの設定を追加 -->
        <jta-data-source>jdbc/mysql</jta-data-source>
        <class>com.example.entity.ArticleEntity</class>
        <properties>
            <property name="eclipselink.jdbc.url" value="jdbc:mysql://localhost:3306?serverTimezone=Asia/Tokyo"/>
            <property name="eclipselink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="eclipselink.jdbc.user" value="xxx"/>
            <property name="eclipselink.jdbc.password" value="xxx"/>
        </properties>
    </persistence-unit>
</persistence>
```

**参考になったサイト（JDBC接続プールとJDBCリソースの追加方法など）**
　http://niwaka.hateblo.jp/entry/2015/02/25/215731
　http://masatoshitada.hatenadiary.jp/entry/2014/12/04/191337
　https://teratail.com/questions/127292

※コマンドでもできるらしい
　https://docs.oracle.com/cd/E19226-01/821-1299/gharo/index.html

```
# grassfishのcliを実行
cd C:\<GrassFishのインストールフォルダ>\glassfish5\bin
asadmin
```

## ふりかえり

- インジェクションする場合コンテナ管理になるので、GrassFishのコネクションプールを利用するらしい
- GrassFish + MySQLを利用する場合気を付ける。