BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース Hibernate が OSGiサポートを追加

Hibernate が OSGiサポートを追加

ブックマーク

原文(投稿日:2013/07/11)へのリンク

Hibernate, 人気のあるJava ORM マネージャは、最近 OSGiのサポートを追加したので、Hibernate をスタンドアローンのJarとしても、OSGiランタイムの両方で使うことも可能になった。一般的にライブラリにOSGiのサポートを追加するのは、MANIFEST.MFに数個のエントリを追加するぐらい、簡単であるが、クラスを探すためにリフレクションを実行するライブラリでは、やるべきことがずっと大変になる。

InfoQ は、Brett Meyer氏、Red Hatのソフトウェアエンジニアで、Hibernate ORM のコア開発者、に困難な事は何であり、いかにそのフィーチャが進化したかを聞いた。

InfoQ: OSGi for Hibernateが可能になったのは最近のバグのように見えますが、リクエストは2008年まで遡ります。どのように修正がなされたのですか?

Meyer: 多くの点で、これは単にコミュニティ主導のプロジェクトの動き方なのです。誰かの興味が特定の主題にそそがれ、何度も解決策が提供され、結局最終結果に落ち着きます。この場合、私は以前、HibernateをOSGi 環境で動かそうとしてました。そこで2012年の8月にチームに参加した時に、それが私の短い優先順位リストにあったのです。数人のコミュニティメンバーがこれに同意して、立ち上げ仕事の一部を始めて、同時に全体的な議論にも貢献しました。

InfoQ: なぜOSGiサポートをHibernateに追加するのは、普通のJavaライブラリよりも難しいのですか?

Meyer: 殆どの難しさは、JPAのORM 実装に固有なことで、複数の ClassLoaders周りに集中しています。スキャニング、エンティティのパーシング、マッピングリソースのパーシング、アノテーションのインデックス化、拡張ポイント実装の登録と実装、デリゲーション、ステートフルネス、キャッシングや他の考慮がこのことを苛つくほど複雑な問題にしました。

Hibernateの "バンドルのファミリー" (1つの"スーパーjar"でなく)におけるスローと動的永続ユニットバンドルを最終的にサポートすることが、事態をもっと悪くしました。

InfoQ: HibernateにOSGiをサポートするのを助けた何か新しいものがありますか?

Meyer: Hibernate ORM 4には, 確かに物事をより簡単にする、幾つかの新しい概念がありました。多フェーズのブートストラップは、リソースのローディングと処理の前に、ClassLoadersと統合フックを提供するのをもっと簡単にしました。統合フック自身は、永続ユニットバンドルで見つかった「拡張ポイント」実装を取り込むのを簡単にしました。

しかし、まだ多くの静的なバンドエイド的な修正があり、それによって現在のアーキテクチャの問題点をかなり明らかになった。Hibernate ORM 5における新しいメタモデルの開発によって、我々のサポートと機能がものすごく増えるでしょう。

InfoQ: どうやって Hibernate ライブラリはJPA クラスの参照を得るのですか?

Meyer: 複数の永続化ユニット、複数のHibernate ORMインスタンス、潜在的に両方の複数バージョンをサポートするために、我々は徹底的にDynamicImport-Packageを避けました。EntityManagerFactory (JPA) あるいは SessionFactory (ネイティブ)がリクエストされた時に、Hibernate ORM OSGiはカスタム ClassLoaderをCore に提供します。そのClassLoader はHibernate バンドルのインスタンスと"リクエストしているバンドル" – 永続化ユニットを持っているバンドルのみを知っています。いつものように、エンティティはユニットによって明示的にリストされるか、スキャンで発見されます。我々はまた、Integratorのような我々の「拡張ポイント」インターフェースの実装を発見できました。この全てに必要なのは、永続化ユニット全体(全てのマッピング、エンティティ、拡張ポイント)がEMF/SFをリクエストしている単一のバンドルに存在することです。

一つのユニットバンドルを必要とすることは、必ずしも理想的ではありません。我々はそれを改善することに取り組んでいます。さらに、それはHibernate ORMの複数インスタンスや複数バージョンをサポートすることは、まだ完全にはサポートされていないことに注意してください。不幸にして、既に述べたようにHibernateのORM 4はまだ非常に静的です。よりダイナミックなセットアップは、Hibernate ORM 5に向けて開発中です。

InfoQ: Hibernate に依存するバンドルを再スタートさせて、それに新しいクラスを正しく掴ますことができますか?

Meyer: 理論的には、"リクエストするバンドル" のClassLoader アーキテクチャによって、そうすることができます。機能は EMF/SFをリクエストしている永続化ユニットバンドルに結びついているので、再スタートはできるはずです。しかし、そのような動的な機能の完全サポートは、Hibernate ORM 5まで実現出来ません。特に綺麗にクリーナップしたりするとなるとですね。

InfoQ: OSGiサポートのテストは、どうしたのですか?

Meyer: コンテナとしてApache Felixを使って、Arquillian上で私が結合/単体テストを書きました。このことがほとんどClassLoadingに関連した、幾つかの本当にユニークな課題をもたらしました。私は最初、テスト実行中に、メモリ上に永続化ユニットバンドルを動的に生成するのにShrinkWrap や Tinybundles が使えると期待してました。しかし、両ソリューションともそれらが原因で、Hibernate ORM Coreがエンティティアノテーションを受け取ると、それらが取り去られました(InputStreams を ShrinkWrapに提供し、それらをCoreで読むのに異なるCLが使われました)。テストランタイムが「リクエストバンドル」(上述の)を上書きしてしまう、というような別の問題もありました。本質的にそれにCL、コンテナ全体を渡しました。問題を解決するために、多くのハッキング的な応急修正を加えました。

結局渡しは、test, testClientBundle, testResultの3つの別々のソースセットを持つことになりました。test セットは、実際のArquillian テストケースを持っています。testClientBundleセットは、永続化ユニットと実際の「ユニットテスト」を持ち、Hibernate ORM OSGi サービス(JPAとネイティブの両方)を使い、結果を検証します。あらゆる障害は、testResult中のinterfaceで定義されたOSGiサービスリファレンスにセットされます。実行の終わりに、サービスは元のテストケースでチェックされます。 CL問題を除いたのに加えて、このことがとにかく、実世界の環境を良くモデル化しています。私は、結局この種の仲介サービスのセットアップが Aries JPA テストの実行方法にかなり近いことを見出しました。私はそこを最初にチェックすべきでしたが。

InfoQ: いかにHibernateをOSGiと使うべきかを示したドキュメントや例がありますか?

Meyer: 始めるのに最高なのは、Developers' Guideです。それには、我々がサポートしている環境の種類や実装の詳細、注意事項が書かれています。またTutorial とQuickStart プロジェクトもあります。詳細な議論を読み通したい人は、最高レベルのOSGi task in JIRAから始めて、そのサブタスク、リンクされたプルリクエストを見るといいです。

OSGiサポートは、先週のHibernate 4.2.3 リリースに含まれている。新しい機能をどう思いますか?

この記事に星をつける

おすすめ度
スタイル

BT