JavaのWebアプリをHerokuでデプロイする方法

JavaのWebアプリをHerokuでデプロイする方法を自分用にメモします。

こちらの記事を参考にしました。
https://phoeducation.work/entry/2021/01/30/143607

#Herokuインストール

まずはHerokuにアカウント登録してください。URL：https://jp.heroku.com/home

次にEclipseで作ったプロジェクトを右クリック → 構成　→ Mavenプロジェクトへ変換
でプロジェクトをMevanプロジェクトにします。pom.xmlが生成されればOKです。

ターミナルを開き、Heroku CLIをインストール

```
$ brew install heroku/brew/heroku
```

デプロイツールをインストール

```
$ heroku plugins:install heroku-cli-deploy
```

Herokuにログイン

```
$ heroku login -i
```

以下のメッセージが表示されるとログイン成功です。

```
Logged in as Herokuに登録したメールアドレス
```

#Heroku上にアプリ作成

Herokuにアプリ領域を作成

```
$ heroku create アプリ名
```

タイムゾーンの設定

```
$ heroku config:add TZ=Asia/Tokyo --app アプリ名
```

以下のコマンドで確認

```
$ heroku run date -a アプリ名
```
現在時刻とJSTが表示されればOK

#デプロイ

あとはEclipseでプロジェクトを右クリックしてwarファイルをエクスポートします。

以下のコマンドでデプロイ

```
$ HEROKU_DEBUG=1 heroku war:deploy warファイルのディレクトリ --app アプリ名 --webapp-runner 8.0.50.0
```

しばらく待って、Doneと表示されればデプロイ成功です。

以下のURLにアクセスすれば表示されます。

https://アプリ名.herokuapp.com/適宜URL

#DBを使ったプロジェクトの場合

DBを使う場合はもう一手間あります。ここではMySQLで解説します。

デプロイする前に以下のコマンドを実行

```
$ heroku addons:create cleardb:ignite --app アプリ名
```

以下のコマンドでURLを確認

Mac
```$ heroku config --app hello-db-norris | grep CLEARDB_DATABASE_URL```
Windows
```> heroku config --app hello-db-norris | findstr CLEARDB_DATABASE_URL```

URLの構造は、mysql://(ユーザー名):(パスワード)@(ドメイン)/(データベース名)?reconnect=true となっています。

HerokuのDBにログインするときは、
```$ mysql -h ドメイン -u ユーザー名 -p パスワード```
でログインできます。

次に以下のコマンドを実行して、文字コードをUTF-8にします。

（Mac）

```
$ heroku config:add CLEARDB_DATABASE_URL='mysql://(ユーザー名):(パスワード)@(ドメイン)/(データベース名)?reconnect=true&useSSL=false&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8' --app アプリ名
```

（Windows）

```
heroku config:add CLEARDB_DATABASE_URL="mysql://(ユーザー名):(パスワード)@(ドメイン)/(データベース名)?reconnect=true^^^&useSSL=false^^^&useUnicode=ture^^^&characterEncoding=utf8^^^&characterSetResults=utf8" --app アプリ名
```

ここまでできたらデータベースにログインしてテーブルを作っていってください。

最後にプロジェクトのDAOファイルに以下のように記述します。

```
private final String DSN = "jdbc:mysql://(ドメイン)/(データベース名)?reconnect=true&useSSL=false&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8";
private final String USER = "(ユーザー名)";
private final String PASSWORD = "(パスワード)";

public Connection getConnection() {
	Connection conn = null;
	
	try {
		// JDBCドライバのロード
		Class.forName("com.mysql.jdbc.Driver");
		
		// データベースへ接続
		conn = DriverManager.getConnection(DSN, USER, PASSWORD);
		
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	} catch (SQLException e) {
		e.printStackTrace();
	}
	
	return conn;
}
	
// Connection型変数が持つデータベースとJDBCリソースの解放
public void close(Connection conn) {
	if (conn != null) {
		try {
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}
	
// PreparedStatement型変数が持つデータベースとJDBCリソースの解放
public void close(Statement stmt) {
	if (stmt != null) {
		try {
			stmt.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}
	
// ResultSet型変数が持つデータベースとJDBCリソースの解放
public void close(ResultSet rset) {
	if (rset != null) {
		try {
			rset.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}
```

あとはwarファイルをエクスポートしてデプロイするだけです。

#詰まった点

いくつか詰まった点があるので、まとめておきます。

・--webapp-runner 8.0.50.0 の 8.0.50.0 は、Webapp Runner のバージョンです。引用：https://search.maven.org/artifact/com.heroku/webapp-runner

8.0.50.0の場合Javaのバージョンが17とかだと動きません。この場合はJavaのバージョンを1.8にしておきましょう。EclipseのPreferenceで「インストール済みのJRE」、Javaの「コンパイラー」を1.8にします。プロジェクトのJavaバージョンも1.8にしておきましょう。

Webapp Runnerのバージョンを9とかにするとJava17でも動くかもしれませんが、確認してないのでご自身で検証してみてください。

・コンテキストパスがなくなる

Herokuにデプロイするとコンテキストパスがなくなります。

例えば、ローカルでは
http://localhost:8080/HelloApp/hello

で表示されていても、Heroku上では
https://アプリ名.herokuapp.com/hello

となり、コンテキストパスのHelloAppは無くなるので注意。ここでだいぶ詰まりました。

・デプロイに失敗する

デプロイに失敗する場合は、warファイルのディレクトリが悪い可能性があります。（warファイルのディレクトリがデスクトップとかだと失敗することがあります。）

warファイルを作ったらそのままディレクトリを動かさず、そのディレクトリにパスを通してデプロイしましょう。例えば、

Eclipseのワークスペース/プロジェクト名/プロジェクト名.war

とかですね。

ここでも相当つまづきました。