独自機能とポータビリティのジレンマ
JBoss / WildFly (全部俺) Advent Calendar 2013の18日目です。
Tomcat, Jetty, WildFly, GlassFish, Resin, WebSphere, WebLogic, Cosminexus, Interstage, WebOTXなどいろいろなJavaアプリケーションサーバがありますが、仕様に準拠するための機能の他に、それぞれ独自の機能を持っていたりします。JBossでも昨日紹介したsarのような独自の機能があります。
独自の機能を考えたときに、常につきまとうのがポータビリティの問題です。不用意な独自機能はポータビリティを阻害しますし、JBossはオープンソースでありポータビリティマターな信条の人が多いので当然これを嫌います。
他のアプリケーションサーバの独自機能の流量制御に依存している、デプロイメント機能にロックインされていて移行できない、というような悲しい話がたまにあるのですが、このような部分は後で困らないようにポータブルに作っておいたほうが良いです。例えば以流量制御については以前書きました。他にもアプリケーションサーバ内で実装されているバージョニングやローリングアップデート依存なんかもポータビリティ問題でよく耳にしますが、アプリケーションサーバの外に枠組み作ったほうがポータブルで安全で柔軟だと思います。
また、独自機能というのは一見ファンシーに見えますが、あとあと問題を引き起す地雷となる可能性があります。
yamadamnさんがJavaアプリケーションサーバでThreadLocal利用時の注意点というエントリを書いていて、TomcatのThreadLocalリークを防ぐ独自機能に触れてWebLogicにも欲しい、とおっしゃっていますが、この機能の存在、そしてデフォルトで有効になっているのは個人的には悪だと思います。本来これはアプリケーションで解放漏れしているのが問題なので、コンテナがその問題を無理やりどうにかしてしまうことで、元の問題がいつまで経っても修正されないという不幸がうまれます。そしていつまでもアプリが修正されないまま他のアプリケーションサーバに移行しようとしたとたんにメモリリークがもりもり発覚する、という不幸も待っています。もちろんアプリとは関係ない運用者には役立つ機能だと思うので、デフォルトはThreadLocalリークの警告のみにして解放機能はOFF、設定でONにできる、という状態のほうが望ましいのではないかと思います。TomcatではThreadLocalリークの最終的な対応としてアプリケーションのundeploy時にスレッドプールを破棄する、ということもしているみたいなのですが、これも本来あるべき姿ではないのでもんにょりします。意味論は置いといてundeployなんてそんなにしないから影響もほとんどないだろうし実装としてアリだという判断も納得できるのですが、クソの上にクソを重ねる感もあります。ジレンマですね。
スレッドがプールされる環境で動作するアプリケーションでは、アプリケーションで利用したThreadLocalはアプリケーションの終了時に参照解放しましょう。以上。
さておき、アプリケーションサーバ実装としては魅力も出さないといけないわけですし、独自機能というのはてっとりばやい手段なのですが、JBoss的にはこの部分でユーザがロックインされてしまうようなものはなるべく避けたい、という思いもあるので難しいところです。アプリケーションサーバとしてのコアの成熟、拡張性、オープンであること、管理運用性の向上というあたりでがんばっています。