WildflyのDataSourceからsupabaseの接続がうまくいかない時の解決策
概要
- Wildflyからsupabaseのデータベースに接続しようとしたら手こずったので、解決方法を残します。
- 具体的には、WildFlyで正しい接続設定をした上でTest Connectionをしても接続に失敗し、エラーのDetailsを見ると、
"WFLYJCA0040: failed to invoke operation: WFLYJCA0047: Connection is not valid"
というエラーが発生していました。
環境
- wildfly: 23.0.0
結論
- 原因は、wildflyの初期設定でJavaアプリケーションのIPv6通信が無効化されていたことによるものでした。
事象が起こるまでの流れ
-
supabaseでプロジェクトを作成し、「Connect」からType「JDBC」を選択し、データベースのホスト名、ポートなどを調べます。
-
wildflyを起動し、管理コンソール(http://localhost:9990/console/index.html)の「Configuration > Subsystems > Datasources & Drivers > Datasources」から、Add Datasourceを選択します。
-
Choose TemplateからJDBC Driverまでを入力し、Connectionに先ほどSupabaseで確認したURLを設定します。
-
その後、Test Connectionをすると概要に添付した画像のように、テストが失敗しました。
解決までの流れ
- WildFlyのサーバーを再起動すると、以下のようなエラーメッセージが出ており、ホストが見つからないとのことでした。
WARN [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (ServerService Thread Pool -- 78) IJ000604: Throwable while attempting to get a new connection: null: javax.resource.ResourceException: IJ031084: Unable to create connection
Caused by: org.postgresql.util.PSQLException: 接続試行は失敗しました。
... 40 more
Caused by: java.net.UnknownHostException: db.xxxxxx.supabase.co
- psqlをすると接続ができたので、ホスト名自体は間違ってなさそうです。
$ psql -h db.*****.supabase.co -p 5432 -d postgres -U postgres
Password for user postgres:
念の為、ホスト名がDNSに登録されているかを確認すると、IPv6で登録されているようでした。
Supabase側で確認すると、Not IPv4 compatibleとあり、IPv4での接続をするにはadd-onが必要らしいことがわかりました。
dig db..*****..supabase.co AAAA
; <<>> DiG 9.10.6 <<>> db..*****..supabase.co AAAA
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59639
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
IPv6あたりが怪しそうとあたりがついたので、wildflyの起動ログを見てみると-Djava.net.preferIPv4Stack=true
というのが設定されていました。(設定した覚えはないので、デフォルトの設定のようです。)
JAVA_OPTS: -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true
これは、Javaのネットワークスタックにおいて、IPv4を優先して使用する(IPv6の接続を拒否する)というもののようです。
原因がわかったので、あとは設定を変更してあげるだけです。wildfly/bin/standalone.conf
を開き、以下の部分から-Djava.net.preferIPv4Stack=true
を削除します。
JAVA_OPTS="-Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true"
wildflyを再起動後、Test Connectionをすると成功しました。
Discussion