23

Tomcat を使用して、WAR ベースのアプリケーションをホストしています。私たちは、org.apache.catalina.authenticator.SingleSignOn を除いて、サーブレット コンテナに準拠した J2EE アプリケーションです。

商用 Java EE アプリケーション サーバーへの移行を依頼されています。

  1. 私が見る変更の最初の欠点はコストです。アプリケーション サーバーの料金に関係なく、Tomcat は無料です。
  2. 2つ目は複雑さです。EJB 機能も EAR 機能も使用していません (もちろん、使用できません)。

それでは、私が見ていない利点は何ですか?

私が言及していない欠点は何ですか?


言及されたのは...

  1. JTA - Java Transaction API - データベースのストアド プロシージャを介してトランザクションを制御します。
  2. JPA - Java Persistence API - JDBC とストアド プロシージャを使用して永続化します。
  3. JMS - Java Message Service - メッセージングには XML over HTTP を使用します。

これでいいです、もっとください!

4

5 に答える 5

59

Java EE6がApacheTomcatをApacheTomEEとして認定することを目標に着手したとき、Java EE6TCKを最終的に通過させるために埋めなければならなかったギャップのいくつかを以下に示します。

完全なリストではありませんが、既存の回答でも明らかではない可能性のあるいくつかのハイライト。

TransactionManagerなし

認定されたサーバーには、トランザクション管理が絶対に必要です。UserTransactionどのWebコンポーネント(servlet、filter、listener、jsfマネージドBean)でも、次のように注入できるはずです。

  • @Resource UserTransaction transaction;

javax.transaction.UserTransactionを使用してトランザクションを作成できるはずです。そのトランザクションの範囲内で触れるすべてのリソースは、すべてそのトランザクションに登録されている必要があります。これには、次のオブジェクトが含まれますが、これらに限定されません。

  • javax.sql.DataSource
  • javax.persistence.EntityManager
  • javax.jms.ConnectionFactory
  • javax.jms.QueueConnectionFactory
  • javax.jms.TopicConnectionFactory
  • javax.ejb.TimerService

たとえば、サーブレットでトランザクションを開始する場合、次のようになります。

  • データベースを更新します
  • トピックまたはキューにJMSメッセージを送信します
  • 後で作業を行うためのタイマーを作成します

..そして、それらのいずれかが失敗するか、単にを呼び出すことを選択するとrollback()UserTransactionそれらのすべてが元に戻されます。

接続プールなし

非常に明確にするために、2種類の接続プールがあります。

  • トランザクション対応の接続プール
  • 非トランザクション対応の接続プール

Java EE仕様では、接続プールは厳密には必要ありませんが、接続プールがある場合は、トランザクションを認識する必要があります。そうしないと、トランザクション管理が失われます。

これが意味するのは基本的に:

  • 同じトランザクションの全員がプールから同じ接続を持っている必要があります
  • 誰かが呼び出しclose()た、または上の他のメソッドに関係なく、トランザクションが完了する(コミットまたはロールバック)まで、接続をプールに戻さないでくださいDataSource

接続プールのためにTomcatで使用される一般的なライブラリはcommons-dbcpです。これをTomEEでも使用したかったのですが、トランザクション対応の接続プールをサポートしていなかったため、実際にその機能をcommons-dbcp(yay、Apache)に追加し、commons-dbcバージョン1.4の時点で存在しています。

commons-dbcpをTomcatに追加するだけでは、トランザクション接続プールを取得するにはまだ十分ではないことに注意してください。トランザクションマネージャーが必要であり、TransactionManagerviaSynchronizationオブジェクトとの接続を登録するための配管を行うためのコンテナーが必要です。

Java EE 7では、DBパスワードを暗号化し、それらをアプリケーションと一緒に安全なファイルまたは外部ストレージにパッケージ化する標準的な方法を追加するという話があります。これは、Tomcatがサポートしないもう1つの機能になります。

セキュリティ統合なし

WebServicesセキュリティ、JAX-RS SecurityContext、EJBセキュリティ、JAASログイン、およびJAACはすべてセキュリティの概念であり、CXF、OpenEJBなどのライブラリを個別に追加しても、デフォルトではTomcatに「接続」されません。

もちろん、これらのAPIはすべて、JavaEEサーバーで連携して動作することを前提としています。Realmこれらすべてを連携させ、Tomcat API上で実行して、既存のすべてのTomcatRealm実装を使用して「JavaEE」セキュリティを推進できるようにするために、かなりの作業が必要でした。それは本当にまだTomcatのセキュリティであり、非常によく統合されています。

JPA統合

はい、JPAプロバイダーを.warファイルにドロップして、Tomcatの助けなしに使用できます。このアプローチでは、次のことはできません。

  • @PersistenceUnit EntityManagerFactoryインジェクション/ルックアップ
  • @PersistenceContext EntityManagerインジェクション/ルックアップ
  • トランザクション対応のEntityManager接続プールに接続
  • JTA-マネージドEntityManagerサポート
  • 拡張永続コンテキスト

JTA-ManagedEntityManagerとは、基本的に、を使用したい同じトランザクション内の2つのオブジェクトEntityManagerが両方とも同じように見え、EntityManager明示的に渡す必要がないことを意味しますEntityManager。このすべての「通過」は、コンテナによって行われます。

これはどのように達成されますか?簡単です、EntityManagerあなたがコンテナから得たものは偽物です。ラッパーです。これを使用すると、現在のトランザクションで実際のトランザクションが検索され、そのトランザクションにEntityManager呼び出しが委任されEntityManagerます。EntityManager.getDelegate()これが不思議な方法の理由であるため、ユーザーは必要に応じて実際のEntityManagerを取得し、非標準のAPIを利用できます。もちろん、細心の注意を払ってこれを行い、デリゲートへの参照を保持しないでください。そうしないとEntityManager、深刻なメモリリークが発生します。デリゲートEntityManagerは通常、トランザクションの完了時にフラッシュ、クローズ、クリーンアップ、および破棄されます。参照を保持している場合は、その参照と、EntityManager場合によってはそれが保持するすべてのデータのガベージコレクションを防ぐことができます。

  • EntityManagerコンテナから取得したaへの参照を保持することは常に安全です
  • への参照を保持することは安全ではありませんEntityManager.getDelegate()
  • EntityManagerあなたが自分で作成したものへの参照を保持するように非常に注意してくださいEntityManagerFactory-あなたはその管理に100%責任があります。

CDI統合

CDIを単純化しすぎたくないのですが、少し大きすぎて、多くの人が真剣に検討していないことがわかりました。多くの人にとって「いつか」のリストに載っています:) 「ウェブガイ」が知りたいと思う。

あなたは典型的なウェブアプリであなたがすることすべてを知っていますか?HttpSession一日中物事を出し入れしますか?キーに使用Stringし、から取得したオブジェクトを継続的にキャストしますHttpSession。あなたはおそらくあなたのためにそれをするためにユーティリティコードに行きました。

CDIにもこのユーティリティコードがあり、これはと呼ばれ@SessionScopedます。注釈@SessionScopedが付けられたオブジェクトはすべて、あなたに代わって配置および追跡されHttpSessionます。を介してオブジェクトをサーブレットに挿入するように要求するだけ@Inject FooObjectで、CDIコンテナは、のトランザクション追跡について説明したのと同じ方法で「実際の」FooObjectインスタンスを追跡しEntitityManagerます。Abracadabra、今あなたはたくさんのコードを削除することができます:)

何かgetAttributesetAttributeしているHttpServletRequest?さて、あなたも@RequestScoped同じ方法でそれを削除することができます。

そしてもちろん、あなたがしているかもしれないとの呼び出し@ApplicationScopedを排除することがありますgetAttributesetAttributeServletContext

さらにクールにするために、このように追跡されるオブジェクト@PostConstructは、Beanが作成されたときに呼び出されるオブジェクトと、@PreDestroy「スコープ」が終了したときに通知されるメソッドを実装できます(セッションが完了し、リクエストが終了し、アプリがシャットダウンします)下)。

CDIはもっと多くのことができますが、それだけで誰もが古いWebアプリを書き直したくなるでしょう。

いくつかの厄介なもの

Java EE 6に追加されたもののうち、Tomcatの操舵室に追加されていないものがいくつかあります。それらは大きな説明を必要としませんが、「ギャップを埋める」の大部分を占めました。

  • へのサポート@DataSourceDefinition
  • グローバルJNDIのサポート(java:global、、)java:appjava:module
  • @Resource MyEnum myEnumおよびを介した列挙型インジェクション
  • @Resource Class myPluggableClassおよびを介したクラスインジェクション
  • へのサポート@Resource(lookup="foo")

マイナーなポイントですが、ポータブルな方法でアプリで定義DataSourceし、Webアプリ間でJNDIエントリを共有し、「これを調べて注入する」と言う簡単な力を持っていると非常に便利です。

結論

前述のように、完全なリストではありません。EJB、JMS、JAX-RS、JAX-WS、JSF、BeanValidationおよびその他の有用なものについては言及されていません。しかし、Tomcatが何であるか、そうでないかについて人々が話すときに見落とされがちなことについての少なくともいくつかの考え。

また、「Java EE」と考えていたものが、実際の定義と一致しない場合があることにも注意してください。Webプロファイルにより、JavaEEは縮小しました。これは、「Java EEが重すぎて、それがすべて必要ない」という問題に対処するためのものです。

WebプロファイルからEJBを切り取った場合、残っているものは次のとおりです。

  • Javaサーブレット
  • Java ServerPages(JSP)
  • Java ServerFaces(JSF)
  • Java Transaction API(JTA)
  • Java Persistence API(JPA)
  • Javaコンテキストと依存性注入(CDI)
  • Bean Validation

これはかなり便利なスタックです。

于 2012-02-08T19:14:46.573 に答える
8

EJBを適切に使用する必要がない限り、フルスタックのJ2EEサーバー(商用かどうかに関係なく)は必要ありません。

フルスタックのJ2EEサーバーがなくても、ほとんどのJ2EE機能(JTA、JPA、JMS、JSFなど)を使用できます。フルスタックj2eeの唯一の利点は、コンテナーがこれらすべてを宣言的に管理することです。EJB3の登場により、コンテナマネージドサービスが必要な場合は、それを使用することをお勧めします。

また、Glasfish、Geronimo、JBossなどの無料のフルスタックサーバーを使用することもできます。

たとえば、Tomcat内で、組み込みのGlasfishを使用して組み込みのj2eeコンテナマネージドサービスを実行することもできます。

クラスタリングやフェイルオーバーを使用する場合でも、セッションBean、メッセージBean、タイマーBeanを適切に管理する場合は、EJBコンテナーが必要になることがあります。

機能のニーズに基づいてアップグレードを検討することを経営陣に提案します。これらのEJBコンテナの中には、Webサーバーとして組み込みTomcatを使用しているものもあるので、何が得られるのでしょうか。

一部のマネージャーは物事にお金を払うのが好きです。市の避難所への寄付を検討するか、BEAに行くように依頼します。

于 2008-11-06T16:11:09.763 に答える
3

商用のJ2EEサーバーに移行するように求められている場合、その理由はJ2EEスタックとは関係がなく、技術的な考慮事項とは関係がない可能性があります。

Tomcatでは得られない商用のJ2EEオファリングで得られるものの1つは、テクニカルサポートです。

Webアプリケーションが満たすはずのサービスレベルによっては、これは考慮事項ではない場合があります。Tomcatの問題を見つけようとしているときにアプリケーションがダウンする可能性はありますか、それとも大きな問題になりますか?

于 2008-11-06T16:31:13.340 に答える
2

実際、膨大な数のパッケージとライブラリが利用可能であるため、最新のサーブレットコンテナ(Tomcat)に追加できないEJBコンテナが提供するものはほとんどありません。したがって、これらの機能のいずれかが必要な場合は、その機能をアプリに統合するプロセスであるコストと言えば、「アラカルト」にすることができます。

これらの機能のいずれかを今「見逃していない」場合は、実用的な観点から、おそらくそれらは必要ありません。

とは言うものの、最新のEJBコンテナーは非常に優れており、これらのサービスがすべて事前に統合されているため、必要に応じて、いくらか使いやすくなっています。機能の統合プロセスを採用のハードルと見なすのではなく、機能を近くに置いておくだけで、アプリケーションでの可能性を探るのに十分な場合があります。

無料のEJBコンテナの品質を考えると、特に現時点で実際の需要がないことを考えると、EJBコンテナを購入することがどのように役立つかを想像するのは非常に困難です。

ただし、実際に入手して試してみて、プラットフォームを探索することをお勧めします。Glassfishは、使い始めるのが非常に簡単で、非常に優れており、WARをそのまま(または非常に小さな調整で)簡単に使用できるはずです。

原則として、TomcatとEJBコンテナの実行の間にある場合、問題は本当になぜそれを使用しないのかということです。特にGlassfishについて言えば、Tomcatよりも使いやすいと思います。主な違いは、Tomcatよりも適度に大きなメモリフットプリント(特に小さなアプリケーションの場合)を持つことができるということですが、大きなアプリケーションでは、それに気付くことさえありません。 。私にとって、メモリヒットは大したことではありませんが、他の人にとっては問題になる可能性があります。

そして、サードパーティのオプションのためにネットをクロールすることなく、このすべての優れた機能の単一のソースを提供します。

于 2008-11-06T16:32:38.300 に答える
2

JBoss や Glassfish などの無料の J2EE サーバーがいくつかあるため、コストは必ずしもマイナス面ではありません。

あなたの質問は、(J2EE = サーブレット + EJB + EAR) を前提としているため、EJB または EAR を使用していない場合、サーブレット コンテナー以外のものを使用しても意味がありません。これはまったく当てはまりません。J2EE には、これ以外にも多くの機能が含まれています。例は次のとおりです。

  • JTA - Java トランザクション API
  • JPA - Java 永続性 API
  • JMS - Java メッセージング仕様
  • JSF - コンポーネントからユーザー インターフェイスを構築する技術

乾杯、ドナル

于 2008-11-06T15:52:40.987 に答える