対象:
JRuby

JDBC利用時、Class.forNameのClassNotFoundExceptionを回避する

JavaのJDBCドライバを利用しようとして、JRubyインストールディレクトリ/libにちゃんとJDBCドライバを配置しているにも拘らず、Class.forNameメソッドでClassNotFoundExceptionがスローされる場合がある。これはクラスローダに起因する問題らしいのだが、回避策の1つはClass.forNameの代わりにjava_importでJDBCドライバをロードする方法である。

java_importではなく、import、include_classを用いても同様の結果が得られるはずであるが、以下の例ではjava_importを用いてJDBCドライバをロードしている。

require "java"

java_import "java.sql.DriverManager"

#java.lang.Class.for_name("com.mysql.jdbc.Driver") # Class.for_nameが失敗する
java_import "com.mysql.jdbc.Driver"

conn = DriverManager.get_connection("jdbc:mysql://localhost/test", "test", "test")

# DBアクセス

conn.close

java_importに渡すドライバ名は変数でも良いので、Class.forNameメソッドと同様に汎用的に利用することができる。特定のJDBCドライバしか利用しないのであれば、そのドライバクラスをnewしてDriverManager.registerDriverに渡す方法でもうまくいくことがある。

require "java"

java_import "java.sql.DriverManager"
java_import "com.mysql.jdbc.driver"

DriverManager.register_driver(com.mysql.jdbc.driver.new)

conn = DriverManager.get_connection("jdbc:mysql://localhost/test", "test", "test")

それでもClass.forNameメソッドにこだわるのであれば、クラスローダを指定する形式のforNameメソッドを呼び出すのも良いだろう。2番目の引数はドライバの初期化を行うか否か、3番目の引数はClassLoaderである。ここで重要となるのは、クラスローダとしてJRuby.runtime.jruby_class_loaderを指定することである。

# ClassLoaderを指定してClass.forName
java.lang.Class.for_name("com.mysql.jdbc.Driver", true, JRuby.runtime.jruby_class_loader) 
(2010/08/07)

新着情報
【オープンソースソフトウェア環境構築】Apple silicon Macで開発環境を構築
【Rust Tips】Actix webでJSONをPOSTする
【Rust Tips】コマンドライン引数を取得する

Copyright(C) 2004-2014 モバイル開発系(K) All rights reserved.
[Home]