Java JDBCで出てくるClass.forName()って、なんなん?




いまさらながら少し面白かったので、ひさびさ書いてみました。

不思議なコード(一部だけ)

さて、こんなコードがあります。

いや、データソース使えよ。とか、そういうのは趣旨から外れるので無しでお願いしますw

何の変哲もない、教本に出てくるようなデータベースに接続するコードです。

でも、よくよく見ると不思議なところがないですか?

ここですな。ま、タイトルに書いてあるから知ってるよね。。

教本だと、「おまじない」or「スルー」ってのがふつうだと思います。
なんとなく呪文を唱えておけばOKって人も多いのではないでしょうか。

んで、「これは何者なんか?」が、今回のお題なわけですが。。

一言で言うなら、コメントの横に書いてあるとおり、答えは「ドライバのロード」です。
ドライバのロードって何?それっておいしいの?レベルで、必要がなさそうな行為です。
ただクラスを使うだけなのに、ふつーこんなことしないよね?

そもそも、こんな呪文って必要なの?

答えはイエスでもありノーでもあるわけなんですが、、、
google先生に見せてもらったjavadocにはこう書いてありました。
ちと古いですが日本語ってことで。読むのめんどいし。

クラスDriverManager
(略)
アプリケーションでは、Class.forName()を使用してJDBCドライバを明示的にロードする必要がなくなりました。現在Class.forName()を使用してJDBCドライバをロードする既存のプログラムは、変更なしで動作し続けます。
getConnectionメソッドが呼び出されると、DriverManagerは、初期化時にロードされたドライバや、現アプレットあるいはアプリケーションと同じクラス・ローダーを使用して明示的にロードされたドライバの中から適切なドライバを探そうとします。
(略)
※DriverManager (Java Platform SE 8)

この前半を読むと「書かなくても良いし、書いたところで害はない」と取れるわけで、、
つまりは、不要。。

だがしかし、そうはいかない(パターンがある)のが世の常です。

たとえば、Tomcatで動かすと、ドライバが見つからないって怒られる(TT)

ってことがあります。(No suitable driver found for…)
この理由はさっきの文章の後半にある「・・・と同じクラス・ローダーを使用して・・・適切なドライバを探そうとします。」です。
言い換えると「見つける努力はしてみたけど、おれには見つけられんかった。。」ってときです。

ま、見つけられんもんは仕方がないですな。

怪しげな言葉「くらす・ろーだー」

少し話題を変えて、さっきのjavadoc。ここには、ちょいちょい「くらす・ろーだー」とか「ろーど」なる単語が並んでいます。
ドライバからデータベースのコネクションがほしいだけなのにね。なぜなんか。。

いろいろ話をすっ飛ばすと、結局のところ、この「くらす・ろーだー」さんは、ドライバが使えるように「ろーど」をがんばっているだけ。
ドライバも単なるJavaのクラスなんで。。クラスである以上、ロードをしないと使えないんで。。

そういえば、DriverManagerは何してるん?

ドライバの管理職であるDriverManagerさんは、「初期化時にロードされたドライバや、現アプレットあるいはアプリケーションと同じクラス・ローダーを使用して明示的にロードされたドライバ」たちの面倒をみてくれます。
逆に言えば、この条件にないドライバさんたちは面倒を見てないので、見つけられません。

ってことで、Class.forName()を唱えて、「JDBCドライバを明示的にロード」して、DriverManagerさんの部下に加わります。
これでDriverManagerがドライバを見つけられるようになる。ってことですね。

ちなみに、ふつーのJavaアプリケーションで同じように作ってみるとわかりますが、必ずしもClass.forName()を唱える必要はありませんw
「JDBCドライバを明示的にロードする必要がなくなりました。」って書いてある通りですね。

んじゃ、やっぱりTomcatが悪いんか??

いや、別に悪いわけじゃないんだけど・・。
Tomcatの「くらす・ろーだー」は少し工夫されているってだけのことです。

Tomcatは、Webアプリケーション(コンテキスト)単位で別ワールドな感じになってます。
ふつー、他のアプリたちは見えないですよね?
Tomcat(VM)的には1つなのに、なぜか見えないですよね。。

この別ワールドの仕組みは「くらす・ろーだー」を分けることで実現されてるってわけです。

んで、こんなことをごにょごにょしているために、うまく見えなかったりするんですねー。

というわけで、まとめ

長すぎるんで、強引に締めにかかるわけですがw

とりあえず「Class.forName()」を唱えておけば、

  • 自分ちの「くらす・ろーだー」がドライバを持ってるjarを探して、
  • ドライバのクラスを「ろーど」する。

そうすると、

  • DriverManagerが探せるようになって、
  • 幸せになれる。

ということでした。
※ドライバがWEB-INF/libとか見える範囲にある前提。

今回はJDBCを例にしましたが、本質的には「くらす・ろーだー」の、ざっくりしたお話しでした。

まじめに書くと長いので、ひかえめに書いたんだけど・・それでも長い。日本語おおすぎ。しかもちょっと遊びすぎました。すみません。
お詫びのしるしにアイキャッチを作ったよw

ちなみに、商用アプリケーションサーバーでは、ちょっとした「くらす・ろーだー」の設定を持ってたりします。
あまりいじる機会は無い設定だとは思うけど。。