🐼

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