Oracle JDBCドライバーを備えた2つのWebアプリが互いに競合するという奇妙な問題があります。 JDBCドライバーJARを共通フォルダーTomcat_HOME/libに配置する必要があります。この理由は何ですか?
JDBCドライバーは、JVM全体のシングルトンに自身を登録します DriverManager
allWebアプリで共有されます。 2つの異なるWebアプリから同じ(クラス名と同じ)JDBCドライバーを2回登録している場合、問題が発生する可能性があります。 Webアプリが同じJDBCドライバーの異なるバージョンを使用している場合、これはさらに問題になります。
また、JDBCドライバーをTomcatのlibフォルダーに配置すると、Tomcatを再起動せずにWebアプリを再デプロイするときにメモリリークを防ぐことができます。新しいWARファイルをTomcatのwebappsフォルダーに入れるだけの場合:
クラスDriverManager
は、bootstrapクラスローダーによってロードされるため、JVMでグローバルに「ライブ」されますが、TomcatはすべてのWebアプリを独自のクラスローダーでロードします。 WebアプリのWEB-INF/libフォルダーはDriverManager
に自分自身を登録し、そのWebアプリのクラスローダーをメモリ(したがって、そのWebアプリのすべてのクラス)に固定し、ガベージコレクションを防ぎます。
代わりにDriverManager
とJDBCドライバーの両方が非Webアプリクラスローダーから提供されている場合、Webアプリクラスが他のクラスローダーからロードされたクラスに固定されることなく、Webアプリを自由に再デプロイできます。
Tomcatの現在のバージョン(おそらく6.xおよび間違いなく7.x)は、特にJDBCドライバーによってメモリリークが検出された場合、Webアプリのアンデプロイに関する警告をログに記録します。