LoginSignup
11
8

More than 5 years have passed since last update.

herokuでjavaからmysql(mariadb)の接続まで

Last updated at Posted at 2015-04-25

前回までの手順

herokuのjavaのサンプルプロジェクト

herokuのGetting Started with Java on Herokuの手順で作成された「java-getting-started(helloworld)」プロジェクトでは、デフォルトでpostgresqlが利用できるようになっている。
これを既存のmysql(実際にはmariadb)に接続する。

手順

手順1:Run the app locally

まず、以下のherokuの手順にしたがって、組み込みのJavaサーバーのJettyが起動することを確認する。
https://devcenter.heroku.com/articles/getting-started-with-java#run-the-app-locally

image

foreman start webの前に、mvn clean installを実行しないとアプリケーションが起動しないので注意する。
foremanは、herokubeltに同封されているProcfileにしたがって複数プロセスを起動することができるツールらしい。
http://qiita.com/7kaji/items/6a59977d2ad85604e7fd

サーバーが起動したら、http://localhost:5000/へアクセスして、Hello from Java!が表示されればOK。
そしたら、foremanは、Ctrl+cで閉じます。

手順2:IntelliJで開く

IDEを使って開発したいため、IntelliJでherokuのサンプルプロジェクトを開きます。

image

「Open」を選択して、「Open File or Project」ウィンドウを開きます。
image

herokuのサンプルプロジェクト「java-getting-started」を選択。
IntelliJが適当にプロジェクトの設定を追加してくれます。
image

手順3:IntelliJ上でMainクラスを起動

IntelliJからMainクラスを実行します。Mainクラスを右クリックから「Run Main.main()」を選択
image

起動に失敗します。
image

Exception in thread "main" java.lang.NumberFormatException: null
    at java.lang.Integer.parseInt(Integer.java:542)
    at java.lang.Integer.valueOf(Integer.java:766)
    at Main.main(Main.java:65)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

Main.javaの65行目を見ます。

public static void main(String[] args) throws Exception {
Server server = new Server(Integer.valueOf(System.getenv("PORT")));

System.getenv("PORT")で値が取れていないようなので、IntelliJのメニューから「Run」-「Edit Configurations」から環境変数を設定します。
image
「Environment variables」が環境変数の指定になります。コードがSystem.getenv()なので、「VM Option」(起動引数)の-Dオプションではダメでした。
image
とりあえず、PORTに5000を設定。(これはforemanのコマンド1つ目のデフォルトポート番号らしいです)
「OK」を押して、 ウィンドウを閉じて、再度、MainクラスをRunする。

2015-04-25 19:04:59.303:INFO::main: Logging initialized @177ms
2015-04-25 19:04:59.412:INFO:oejs.Server:main: jetty-9.2.10.v20150310
2015-04-25 19:04:59.458:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@3ada9e37{/,null,AVAILABLE}
2015-04-25 19:04:59.479:INFO:oejs.ServerConnector:main: Started ServerConnector@490d6c15{HTTP/1.1}{0.0.0.0:5000}
2015-04-25 19:04:59.480:INFO:oejs.Server:main: Started @357ms

こんな感じで起動するので、http://localhost:5000/にアクセスする。
おなじみのhelloメッセージが表示されるはずです。

また、以下のようにjava.net.BindException: Address already in useのようなエラーがでる場合は、他のプロセスで5000番ポートを利用しているので、探しだしてkillするか、IntelliJの環境変数のPORTの番号をずらしましょう。

2015-04-25 19:06:30.342:INFO:oejs.Server:main: jetty-9.2.10.v20150310
2015-04-25 19:06:30.381:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@3ada9e37{/,null,AVAILABLE}
2015-04-25 19:06:30.393:WARN:oejuc.AbstractLifeCycle:main: FAILED ServerConnector@5f5a92bb{HTTP/1.1}{0.0.0.0:5000}: java.net.BindException: Address already in use
java.net.BindException: Address already in use
    at sun.nio.ch.Net.bind0(Native Method)
    at sun.nio.ch.Net.bind(Net.java:436)
    at sun.nio.ch.Net.bind(Net.java:428)
    at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214)
    at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
    at org.eclipse.jetty.server.ServerConnector.open(ServerConnector.java:321)
    at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:80)
    at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:236)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.server.Server.doStart(Server.java:366)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at Main.main(Main.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

手順4:mysqlに接続してみる

デフォルトのpostgresqlを利用するのではなく、現行稼働しているmysql(実際はmariadb)に接続してみます。
サンプルプログラムを流用して、自前で用意したmysqlへ接続します。

pomファイルにmariadbのコネクタのライブラリを設定

すみません、mysqlの方は読み替えてください。
mariadbの最新のコネクタライブラリを探す。

googleで検索すると以下のページが引っかかるので参考にします。
http://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client/1.1.8

以下の設定をpom.xmlに追記します。postgresqlの設定は消しても大丈夫です。

<dependency>
    <groupId>org.mariadb.jdbc</groupId>
    <artifactId>mariadb-java-client</artifactId>
    <version>1.1.8</version>
</dependency>

mariadbへの接続設定を環境変数に設定

herokuのサンプルでは、heroku configの設定情報からpostgresqlのホスト、ユーザー、パスワードを取得してデータベースコネクションを取得しています。
heroku configの例

~/D/g/java-getting-started ❯❯❯ heroku config
=== dry-bayou-2092 Config Vars
DATABASE_URL:                postgres://xxxxxxxxxxxxxx:yyyyyyyyyyyyyyyyyyyyyyyyyy@ec2-99-999-999-99.compute-1.amazonaws.com:5432/zzzzzzzzzzzzzz
HEROKU_POSTGRESQL_MAUVE_URL: @ref:aaaaaaaa-bbbbbbb-9999:url
JAVA_OPTS:                   -XX:+UseCompressedOops
  • xxxxxxxxxxxxxx ユーザーID
  • yyyyyyyyyyyyyyyyyyyyyyyyyy パスワード
  • ec2-99-999-999-99.compute-1.amazonaws.com ホスト
  • 5432 ポート番号
  • zzzzzzzzzzzzzz データベース

postgresqlの設定を参考にして、環境変数に以下を設定します。

mariadb://userid:pasword@localhost:3306/database

「Run」-「Edit Configurations」の「Environment Variables」に環境変数「DB_URL」を追加
image

userid、pasword、database等は自分の環境に合わせて変更してください

mariadbへ接続するようにJavaコードを変更

サンプルコードのgetConnectionメソッドのDATABASE_URLDB_URLに、postgresqlmariadbに変更します。

Main.java(変更後)
  private Connection getConnection() throws URISyntaxException, SQLException {
    URI dbUri = new URI(System.getenv("DB_URL"));

    String username = dbUri.getUserInfo().split(":")[0];
    String password = dbUri.getUserInfo().split(":")[1];
    int port = dbUri.getPort();

    String dbUrl = "jdbc:mariadb://" + dbUri.getHost() + ":" + port + dbUri.getPath();

    return DriverManager.getConnection(dbUrl, username, password);
  }

手順5:DB接続を確認

Mainクラスを再度実行して、今度は、http://localhost:5000/dbにアクセスします。
Servletでmariadbへの接続がうまくいけば、ticksテーブルが作成され、INSERT INTO ticks VALUES (now())で現在時刻がテーブルに登録されます。
その結果がWebページに表示されれば成功です。

image

herokuにデプロイする前に

herokuの環境変数にmaridadbの接続設定を追加します。

heroku config:set DB_URL=mariadb://userid:pasword@localhost:3306/database
11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8