MySQL8.0(Docker)+LastaFluteの開発環境を作りました

Dockerを最近知ったので、LastaFluteでの開発環境を作ってみたらいろいろハマったのでメモです。

本当にDocker初心者なのでDockerFileやDocker Composeの知識はまだあまりありません。
java開発環境(eclipse)のコンテナ化もイマイチよくわからないのでコンテナ化しているのはMySQLだけです。(javaコンテナ内のマウントフォルダにeclipseをダウンロードして使う???)
誰かいい方法を教えてください。

【環境】
Windows 10 Pro
docker desktop 2.1.0.1
MySQL 8.0.17
eclipse 2019-06(4.12.0)
LastaFlute 1.1.3
DBFlute 1.2.0
MySQL JDBC 5.1.47

広告

MySQLのコンテナを作成

【PowerShell】
docker run -d --name my-database -p 3306:3306 -e MYSQL_ROOT_PASSWORD=rootpassword -v my-volume:/var/lib/mysql -v ${PWD}/db/conf:/etc/mysql/conf.d mysql

my-databaseという名前で最新のMySQL(8.0.17)のコンテナを作成しました。
cnfファイルの内容は、LastaFlute公式の推奨設定に少し追加した内容です。

【cnfファイル】
[mysqld]
character-set-server=utf8mb4
lower_case_table_names=1

collation-server=utf8mb4_general_ci

# to avoid easy deadlock of repeatable-read
transaction-isolation=READ-COMMITTED

# TRADITIONAL contains STRICT_ALL_TABLES, NO_ZERO_DATE and so on...
sql_mode=TRADITIONAL

[client]
default-character-set=utf8mb4

LastaFluteプロジェクトを作成

以前に自分で書いた記事を見ながら作成。
今回はandroidアプリ用の処理を作りたかったので、jsonを返すhangerプロジェクトから作成しました。

プロジェクト名とアプリ名が思いつかなかったので2つとも同じ名前にして生成したのがひとつ目のハマりポイント。(下記の★マークの箇所)

【StartupTest.java】
    public void test_startup_actually() throws Exception {
        final File repositoryDir = getProjectDir().getParentFile();
        final String domain = "ozanote.com";
        final String serviceName = "ozanote"; ★
        final String appName = "ozanote"; ★
        startupLogic.fromHangar(repositoryDir, domain, serviceName, appName);
        refresh(serviceName, appName); // for retry
    }

ビルドするとエラーが大量に。

エラー:型 RootAction の階層は不整合です

エラー内容は”型 RootAction の階層は不整合です“でした。
さらに継承元の OzanoteBaseAction に移動してみると別のエラー“循環が検出されました。型 OzanoteBaseAction は自分自身または自分のメンバー型の 1 つを拡張/実装できません”が発生。

エラー:循環が検出されました。型 OzanoteBaseAction は自分自身または自分のメンバー型の 1 つを拡張/実装できません

よく見ると継承元と継承先のクラス名が同じになってしまっています。
サービス名とアプリ名は違うものにしないといけなかったようです。
面倒くさがらずにちゃんと考えるべきでした。(反省)

アプリ名を”android”に変更して再作成。

エラー解消

エラーは出なくなりました。

replaceScheme実行

エラーになりました。

【エラーログ抜粋】
[df-replace-schema] [SQLState]
[df-replace-schema] 28000
[df-replace-schema]
[df-replace-schema] [ErrorCode]
[df-replace-schema] 1045
[df-replace-schema]
[df-replace-schema] [SQLException]
[df-replace-schema] org.dbflute.exception.DfJDBCException
[df-replace-schema] Failed to connect: url=jdbc:mysql://localhost:3306/ozanotedb user=ozanotedb
[df-replace-schema]
[df-replace-schema] [NextException]
[df-replace-schema] java.sql.SQLException
[df-replace-schema] Access denied for user 'ozanotedb'@'172.17.0.1' (using password: YES)

エラーメッセージを見ると、ozanotedbユーザーで接続できなかったようです。

DBユーザー

ozanotedbユーザーはちゃんと作成されているので、接続の問題?
ふたつ目のハマりポイントでした。

MySQLのlocalhostはDockerコンテナ内なので、ホストOSから接続するためにはlocalhostではなくIPを指定してユーザー作成しないといけませんでした。
ここで指定するIPはゲートウェイで、基本的に”172.17.0.1″になるようです。
※PowerShellで[docker network inspect bridge]を実行すると確認できます。

replace-schema-00-system.sql を編集。
localhost → 172.17.0.1

localhostを172.17.0.1に変更

replaceSchemeを実行すると、次は別のエラーが発生しました。

【エラーログ抜粋】
[df-replace-schema] [SQLState]
[df-replace-schema] 42000
[df-replace-schema]
[df-replace-schema] [ErrorCode]
[df-replace-schema] 1064
[df-replace-schema]
[df-replace-schema] [SQLException]
[df-replace-schema] com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException
[df-replace-schema] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'MEMBER

“MEMBER”あたりで構文エラー。
これに関しては jflute さんがTwitterで話題にされていたのですぐ解決しました。

MEMBERテーブルを使用しなければいいのですが、とりあえず動く状態に持っていきたいので暫定対応でテーブル名をMEMBERSHIPに変更しました。
以下のファイルが対象です。

  • replace-schema-10-basic.sql
  • take-finally.sql
  • cyclic-data-01-MEMBER-plus.xls

いくつかあるので検索しながら変更しました。
その他にも、replace-schema-10-basic.sql の”FK_MEMBER_MEMBER_STATUS”を”FK_MEMBERSHIP_MEMBER_STATUS”に変更しないと命名規則エラーになりました。

再びreplaceSchemeを実行し、やっと成功。

replaceScheme成功

ビルド

ozanote-common の maven-install でエラー。

【エラーログ抜粋】
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project ozanote-common: Compilation failure
[ERROR] No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?

エラーメッセージにある通り、JREが使用されていたのでJDKに変更してビルド完了。

実行

ozanote-android の AndroidBoot.javaを実行し、URLにアクセス。
試しにサンプルユーザー(account:Pixy, password:sea)でログインしてみます。

エラーになりました。

【エラーログ抜粋】
[SQLState]
42000

[ErrorCode]
1064

[SQLException]
org.lastaflute.jta.exception.LjtSQLException
Failed to execute the SQL: select count(*)
  from MEMBER dfloc
    inner join MEMBER_SECURITY dfrel_3 on dfloc.MEMBER_ID = dfrel_3.MEMBER_ID
 where dfloc.MEMBER_ACCOUNT = ?
   and dfrel_3.LOGIN_PASSWORD = ?
   and dfloc.MEMBER_STATUS_CODE in (?, ?)
-- com.ozanote.app.web.signin.SigninAction@index():

MEMBERテーブルをSELECTしようとしてエラーになっています。
テーブル名の変更対応に漏れがありました。
ozanote-common の com.ozanote.dbflute 配下の Memberテーブル関連のクラス名を片っ端からMembershipにリファクタリングします。

regenerate を実行後、AndroidBoot.java を再起動してログイン。

成功し、認証キーが表示されました。
疲れたー。

次回はLastaFluteのログイン処理をfirebaseの認証を使うように変更してみようと思います。(手こずりそう。。。)