はじめに

この記事は、Google App Engine Standard for Java 17/21環境でOracle DatabaseとJDBC接続するアプリケーションを運用・保守している方を対象としています。
ローカルでは問題なく動作していたコードが、GAEにデプロイすると起動ログに

oracle.jdbc.driver.OracleDriver registerMBeans: Error while registering Oracle JDBC Diagnosability MBean

という警告が大量に出力され、Stackdriver Loggingの無料枠を圧迫してしまう――という事象に悩まされている方は多いはずです。
本記事を読むことで

  • 当該ログが出力される仕組み
  • 警告を完全に消すための3つの対処法
  • 本番環境で推奨される接続設定

がひと通り理解できます。GAEでOracle JDBCを使う前に知っておくと得する情報も合わせてお届けします。

前提知識

  • Java 11以降のServlet開発経験
  • Maven/Gradleでの依存管理の基本
  • Google App Engine Standardのapp.yaml/appengine-web.xmlの記述 (Oracle Database自体の知識は不要です)

GAE + Oracle JDBCが組み合わさると起きる「registerMBeans」警告の正体

App Engine Standardはセキュリティモデル上、ユーザーアプリケーションがJMX(Java Management Extension)のMBeanサーバーに対して自由にリソースを登録できません。一方、Oracle JDBCドライバ(ojdbc8/ojdbc11)の内部には、データベース接続プールやSQL実行統計をJMX経由で公開するための「OracleDiagnosabilityMBean」が実装されており、クラスロード時に自動的にregisterMBeans()が呼ばれます。GAEはこの登録を許可しないため、標準エラーに先頭の警告が出力される、というわけです。エラーと書かれていますがJDBCの機能制限には一切影響しないため、単純にログを消したい、というニーズが多いです。

具体的な手順:ログを抑制する3つの方法

以下、2025年1月時点で動作確認済みの対処法を紹介します。すべて「アプリケーションコードへの変更なし」で実施できます。

ステップ1:システムプロパティでMBean無効化(最速)

Mavenであればpom.xmlのappengine-maven-plugin、Gradleであればbuild.gradleのappengineブロック内に

<systemProperties>
  <property>
    <name>oracle.jdbc.disableJmx</name>
    <value>true</value>
  </property>
</systemProperties>

を追加してデプロイするだけです。これによりOracleDriverのクラスイニシャライザがMBean登録をスキップします。即効性があり、GAEのバージョンを問わず動作します。

ステップ2:ロギングフィルタで出力を抑える(より高度な制御)

src/main/resourcesにlogging.propertiesを配置し

.level = INFO
# Oracle JDBCのMBeanログのみWARN以上に上書き
oracle.jdbc.level = SEVERE
java.util.logging.ConsoleHandler.level = INFO

を記述したうえで、appengine-web.xmlに

<system-properties>
  <property name="java.util.logging.config.file" value="WEB-INF/classes/logging.properties"/>
</system-properties>

を追記します。こうすると、MBean警告が出ても標準出力にINFOレベルで出力されず、Stackdriver側でフィルタリングできます。

ステップ3:Thin Driverへの切り替え(将来的な推奨)

Oracle 19c以降では「ojdbc8/11-production.jar」に代わって「ojdbc8/11-thin.jar」が提供されており、JMXモジュールが含まれていません。依存を差し替えるだけで警告が出なくなる上、JARサイズも約30 %削減できます。Maven Centralの座標は

<dependency>
  <groupId>com.oracle.database.jdbc</groupId>
  <artifactId>ojdbc11-thin</artifactId>
  <version>23.3.0.23.09</version>
</dependency>

です。ただしThin DriverはOracle Cloudのみでテストされているため、オンプレDBを利用している場合はステップ1/2のほうが無難です。

ハマった点:システムプロパティが適用されないケース

GAE Standard for Java 21では、従来のappengine-web.xmlのが非推奨になり、代わりにapp.yamlのenv_variablesが使われます。ここでoracle.jdbc.disableJmxを設定しても、OracleDriverはクラスロードが完了しているため反映されません。回避策として、ServletContextListenerのcontextInitialized()内で

System.setProperty("oracle.jdbc.disableJmx", "true");

を明示的に呼ぶか、ステップ2/3を併用する必要があります。

解決策

結論として、本番稼働中のアプリケーションに最小の変更で適用できるのは「ステップ1(+リスナーでの上書き)」です。新規プロジェクトであれば「ステップ3:Thin Driver」に移行するのが得策でしょう。どちらにせよ、MBean警告が出たからと言ってOracle接続が不安定になることはありません。

まとめ

本記事では、Google App Engine StandardでOracle JDBCドライバを利用する際の

  • registerMBeans警告のメカニズム
  • ログを抑制する3つの実装パターン
  • Java 21移行時の落とし穴

を解説しました。

  • システムプロパティoracle.jdbc.disableJmx=trueを設定すれば即座にログが消える
  • ロギングレベルでフィルタリングすれば、他のOracle JDBCログも柔軟に制御できる
  • 将来的にはThin Driverへの切り替えでJARサイズとログの両方を改善できる

この記事を通して、GAEでOracle Databaseを使う前に「なぜMBean警告が出るのか」「どうすればスッキリさせられるのか」が理解できたでしょう。次回は、同環境でHikariCPを使った接続プール設定と、Cloud SQL for Oracle(近日提供予定)との比較についてお届けします。

参考資料