S_a_k_Uの日記みたいなDB

~サクゥーと呼ばないで~

H2DBでデータベース新規作成

久しぶりにH2でデータベースの環境を作っててハマったのでメモ。
OS:Windows11
H2DB:H2 2.2.220 (2023-07-04)
Java:java version "20.0.2" 2023-07-18

以前も同じような感じで一瞬ハマったけど、その時はインストーラを使用してインストールして、タスクトレイのDB作成画面(Create a new database...)から新規作成できた。
今回はインストーラを使わずに、zipファイルから解凍して手動でサービス登録など行ったため、改めて手順をメモ。

手順

zipファイルを解凍(インストーラ未使用)

インストールしたディレクトリのパス:%H2DB_HOME%

サービスとして登録

%H2DB_HOME%\service\1_install_service.batを実行。

サービスを開始

Windowsのコンピューターの管理のサービス画面からH2 Database Engine Serviceを開始。
または
%H2DB_HOME%\service\2_start_service.batを実行。
これがハマるきっかけ
サービスを開始後、%H2DB_HOME%\service\3_start_browser.batを実行してコンソールを起動し、コンソールから初回接続で新規作成しようとすると、以下のようなメッセージが表示され、DBが作成できない。

Database "<作成されるDBのパス>" not found, either pre-create it or allow remote database creation (not recommended in secure environments) [90149-220] 90149/90149 (ヘルプ)

サービスで実行中のプロセスではDBが作成できないらしい。
メッセージの内容からすると、セキュリティ関係の制約???
サービスの起動ユーザーをAdministratorsなユーザーにして開始して、コンソールから初回接続を試みたが、同様のメッセージが表示され、DBが作成できない。
インストーラでインストールした時に使用できた、タスクトレイから起動できるDB作成画面ってJavaコマンドから起動できんのかな?と調べてみたが見当たらない…

サービスを一旦停止

Windowsのコンピューターの管理のサービス画面からH2 Database Engine Serviceを停止。
または
%H2DB_HOME%\service\4_stop_service.batを実行。

コンソール(org.h2.tools.Console)の起動

コマンドプロンプトからコンソールを起動する。

java -cp %H2DB_HOME%\bin\h2-2.2.220.jar org.h2.tools.Console

サービスが開始されていないため、%H2DB_HOME%\service\3_start_browser.batではコンソールは起動しない。

コンソールからDBを新規作成

設定名は「Generic H2 (Embedded)」のまま、「JDBC URL」で作成すべきDBのパスを指定して初回接続する。
ここで上記のようなメッセージは表示されず、空のデータベースに接続することができた(=空のデータベースが作成できた)。
 
なお、上記のコンソールを起動するコマンドを実行すると、タスクトレイにH2DBのアイコンが表示され、そこからDB作成画面を開き、作成することも可能。

コンソール(org.h2.tools.Console)の停止

コマンドプロンプト上のプロセスでコンソールが起動しているのでCtrl+Cで強制終了する…
初回はそのような手順としたが、やっぱり真っ当な方法と思えないので、タスクトレイにH2DBのアイコンから終了(Exit)させるのが正解っぽい?
コンソール(org.h2.tools.Console)を停止せずにサービスを開始すると、以下のようなエラーとなる。

ローカルコンピュータの H2 Database Engine Service サービスを開始できません。
エラー 1067:プロセスを途中で強制終了しました。

逆に、サービスを停止せずにコンソール(org.h2.tools.Console)を起動すると、以下のようなエラーとなる。

The Web Console server could not be started. Possible cause: another server is already running at http://xxx.xxx.xxx.xxx:8082
Root cause: ポート "8082" をオープン中に例外が発生しました (ポートが使用中の可能性があります)
Exception opening port "8082" (port may be in use), cause: "java.net.BindException: Address already in use: bind" [90061-220]
Exception in thread "main" org.h2.jdbc.JdbcSQLNonTransientConnectionException: ポート "8082" をオープン中に例外が発生し
ました (ポートが使用中の可能性があります)
Exception opening port "8082" (port may be in use), cause: "java.net.BindException: Address already in use: bind" [90061-220]
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:690)
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:489)
        at org.h2.message.DbException.get(DbException.java:212)
        at org.h2.util.NetUtils.createServerSocketTry(NetUtils.java:211)
        at org.h2.util.NetUtils.createServerSocket(NetUtils.java:177)
        at org.h2.server.web.WebServer.start(WebServer.java:409)
        at org.h2.tools.Server.start(Server.java:536)
        at org.h2.tools.Console.runTool(Console.java:210)
        at org.h2.tools.Console.main(Console.java:72)
Caused by: java.net.BindException: Address already in use: bind
        at java.base/sun.nio.ch.Net.bind0(Native Method)
        at java.base/sun.nio.ch.Net.bind(Net.java:556)
        at java.base/sun.nio.ch.Net.bind(Net.java:545)
        at java.base/sun.nio.ch.NioSocketImpl.bind(NioSocketImpl.java:634)
        at java.base/java.net.ServerSocket.bind(ServerSocket.java:393)
        at java.base/java.net.ServerSocket.<init>(ServerSocket.java:275)
        at java.base/java.net.ServerSocket.<init>(ServerSocket.java:168)
        at org.h2.util.NetUtils.createServerSocketTry(NetUtils.java:207)
        ... 5 more

サービス側のプロセスとコマンドプロンプト側のプロセスで、同じポートを使おうとしてるからなのね。

サービスを再度開始

上記と同じ

コンソールから接続

%H2DB_HOME%\service\3_start_browser.batを実行しコンソールを起動。
先ほど新規作成した空のDBに接続される。