これは Java EE Advent Calendar 2014 の2日目です。
Java EE をよくわかっていない私がよくもまぁアドベントカレンダーなんて登録したなーとしみじみ思いながら。 確かアドベントカレンダーに登録したのをきっかけに、なんか調べようと思ってたのですが、 思ったより12月が来るのが速くて無理でした!
そんなこと言っていても仕方ないので、今書けるものを書くとしましょう。そうしましょう。
Java EEってなんぞ
Java EEはJavaのEnterpriseEditionのことで、企業向けとかだけど、なんかサーバーとか使うせいか、Webっぽい雰囲気がある物体です。また、Java EEはいくつかのJSRをまとめたJSRのことを指したりもします。 こういうJSRを"アンブレラJSR"と言うとか言わないとか。
JSR(Java Specification Request)は、おおざっぱに言えばJavaの仕様のこと。 仕様書とTCK(Technical Compatibillity Kit)と参照実装(RI/Refarence Implementation)でなりたってます。 JSRはすべてJavaの標準ライブラリに入ったりするわけではなくて、たとえばJava SEに何を入れるかとかもアンブレラJSRで決めます。 たとえばJava SE 8はJSR-337で、こいつを見ればJava SE 8でどのJSRが入ったかはわかる気がします。読んでないけど。
で、同じようにJava EE 7もJSR-342なわけで、この一式を揃えているものがJava EE 7サーバー(EEサーバーと言ったりする)を名乗ることができます。フルプロファイルとかWebプロファイルとかあるけど、その辺は割愛。 例えばGlassFishやJBoss/WildFlyなどはEEサーバーですが、TomcatやJettyなどはServletとかJava EEにも含まれる一部のJSRを実装(もしくは実装したものを使用)していますが、一式揃ってないのでEEサーバーではありません。 EEサーバーかどうかで何が変わるかと言うと、無いものは自分で追加しなきゃいけないってことです。 たいていは使いたいものを持ってきて突っ込めば動きますが、組み合わせは誰も保証してくれないから、開発者がちゃんとしないといけないので、そこそこ大変。かも。稀によく動きませんし。 そんなわけで、Java EEの一式を使いたいなら、EEサーバーを使うのが順当になるのかなと思っています。
全部入りで便利に思えるEEサーバーですが、万能なわけではありません。 各JSRの実装をEEサーバーが提供するため、個別にバージョンを変えることは難しかったりするようです。 そんなことはそうそう無さそうに思えるかもしれませんが、Java EEの仕様のいくつかはまだ発展途上で、Java EE 6のころはJAX-RSやCDIの次のバージョンを使いたくなることはしばしばあったようです。 他にも提供されるものではなく別の実装を使いたい場合とか、そう言うときもあったりとか。 なんだかんだで固有の機能ってありますしね。 で、変えられなくて困ったとかなんとか。
昔は全部入りなので重いとかもよく言われましたが、モジュール化とかその辺があれでWildFlyの起動は1秒程度になってたりします。 思い込みでEEサーバーは重いだとか言わないように注意しましょう。 まぁ起動の速さは諸々のアレコレを後回しにしてるからなんで、あれはそれなんですが。(よくわかってない)
<追記 時間="2014/12/4 9:23">
WildFlyは起動時に必要なものについては一切後回しにしてないですよっと。ログ詳細にしてもstartup time報告された後になんかログでてたりとかしないはずです。 http://t.co/8oHcp3CaTL
— Takayoshi Kimura (@nekop) 2014, 12月 3
</追記>
とりあえずEEサーバーについての一覧はこれかな。
ラインナップとかバージョンとか
現時点の最新はJava EE 7です。そのうちJava EE 8が出るです。 ラインナップは以下のサイトを見て……
……もダメです。EE7のこと書いてるのか6のことなのか5のことなのかまじわからん。 こういう時は英語を見るのです。アドレスバーからjp削ればだいたい行けるですね。
Java EE - Technologies | Oracle Technology Network | Oracle
なるほど、わからん?まぁそういうもんということで……。
あとはJava EEのバージョンなんだけど、Javaのバージョンって言うとたいていJava SEのバージョンだったりします。 で、EEとSEの番号は今んところ順番に上がってる感じなので混ざりやすい。 SE6→EE6→SE7→EE7→SE8って感じ。 なので「EEのバージョンはSEの1つ下」なんてたまに言われますが、ソンナコトナイ。 GlassFish4やWildFly8はJavaSE7/EE7で動くって感じだし。
そいやWildFlyは8.2が出て、中で使ってるもののバージョン上がっちゃってたりする。 代表的なCDI1.2とWebSocket1.1はともにJava EE 7のバージョンより次のになってる。 なので、EEサーバーって言っても全部そのバージョンでかためるってもんでもない。 そりゃそうなんだけども。
ユニットテストについて
Java EEに含まれるものを使ってアプリケーションを作るのはいいんだけど、ユニットテストが難しいか、無理な感じなのは厄介。 アプリケーションサーバーの機能を使うのだから、テストできなくてあたりまえなんだけど、APIの使い方とか間違ってないかを動かして確認したいわけです。ユニットテスター(?)としては。
確かに組み込みJetty(Servletのテストしたいとき)やGlassFishを使ったり、Arquillianを使えばJUnitとかでテストは実行できるんだけど、求めてるのはそこじゃなくて。 完全な環境でしっかり動くことと言うより、軽くインタフェースレベルの齟齬がないかくらいは手元で確認したいわけですよ。
まぁそんなことでなんやかんやとしてユニットテストを書いて動かそうとすると、ClassFormatErrorとか謎の例外が出たりする。この辺の事情で。java-ee-apiを使うのが正しいぽいのに何て事だと。これでjavax.injectとかservlet-apiとかを個別に依存に入れ始めると、それはそれでどうなのと思ったりもするわけですよ。自分で依存書いちゃうとバージョン間違えたりするし。たまにしてるの見るし。
普段使うもの
気を取り直して、普段使うJava EEの中身について思うところを。Java EEの中には色んなものが入っていますが、完全にJava EEに乗っかるとしても全部を使わなきゃいけないわけじゃありません。使わないものもあるし、よく使うものもあります。てことで、まずはよく使うものについて。
Servlet は昔からあるJavaのサーバーサイド技術で、根幹の1つと言っても過言じゃないでしょう。 一昔前はServlet/JSPの本が巷にあふれていましたが、流石に最近は減ってきて……ないか。 現在はServletを直接使うことは稀ですが、FilterやListenerあたりはよく使います。あまり代替がない感じ。 Servlet3.0でこの辺りも更新されて、web.xmlに書かずともアノテーション付けておけば自動的に動いたりする素敵な感じになっているようですが、その辺りの機能はそれほど使えていません。全部互換性とかが悪いんや。
古くさい雰囲気のあるServletかもしれませんが、去年どこぞで出たベンチマークでキモい結果を出してたりして、Javaが遅いとは何なんだろうってなったのは記憶に新しい。「Javaが遅い」の大半は起動速度で、JVMが立ち上がる時にもろもろロードしなきゃだから云々だったりするので、実行速度の話と混同してはいけない。
JSP も昔からあるものですが、最近は若干下火かなと。でも結構使います。 個人的な趣味ではJSPでもJSFでもなくThymeleafとかテンプレートエンジンとかにしてしまいたいと思ってる。 とは言え、なんか独自タグとか、JSP前提にした標準とかあって、ひっくり返してまでのメリットはなかなか見えない。 JSPが嫌なのはJSPエンジン通さないとデザインすら見れなくて、直して確認してってのがウザいから。 EclipseのWTP使ったり、Jetty使ったりとかで効率は上げれなくは無いんだけど、やっぱり好かない。
JTA とか JMS とかは普通に使って普通にハマってます。 気が向いたらそのうちなんか書くかも。気が向いたら。
JAX-RS は @backpaper0 さんに感化されてるので、趣味で触る時はもっぱらこれ。
気にしてるもの
JSF はチュートリアルレベルしか触ったことが無いのでなんとも。 あまり好きくないんだけど、食わず嫌いもなーと思いつつ、そんな手を広げられない現状。 別に一生食べなくてもいい食べ物ってあるよなとか適当なこと思ってます。
JavaBatch(JSR-352) は一度ちゃんと触っておきたいなと思ってたら、SpringBatchが実装っぽくて、あーってなってる。 とは言えバッチフレームワークはおさえておきたいなとは思ってる。 EEじゃなくSE環境でも使えるぽいし。
JSON-P(JSR-353) も気にはなってるけど、気になってる程度。 標準で普通に使えるなら嬉しいところだけど、それならSEに入って欲しいところだけど、SEに入られてバージョン差異が云々とかなるとそれはそれで面倒だしと。
Concurrency Utilities(JSR-236) はいいなーと思ってるんだけど、なかなか使いどころの難しい並行処理さん。 ところでJSR-237さんはどうなったんだろう、とか思ったり思わなかったり。吸収合併?
CDI(JSR-346) はなんかでかくなっていくなーと眺めてるなう。 EJB との使い分け云々の話も出てくるけど、あんまEJB興味無(以下略
あまり興味の無いもの
書いてないやつはそういうことなのかも。 でも私結構移り気なので、ちょっと触ったりしたら興味がわいちゃって来週には「xxxいいよ!」とか言ってるかも。 これからのアドベントカレンダーに期待ですね!
急募)アプリケーションサーバー
Java EE 7になって開発効率性だとかで結構魅力的なラインナップが揃ってきているので、すぐ使いたい気分にはなるのですが、どうしてもアプリケーションサーバーの対応がネックです。 仕様がいくらできても、サーバーが無くては動かせませんからねー。 JSRは前述の通り参照実装も含めてリリースになるので、参照実装のGlassFishも同時に出るわけだけど、商用サーバーが無いと動かしにくい組織とかも結構あるわけでして。 こればっかりは待つしかない状況。ぐぬぬ。