2

2 つの EJB を持つアプリケーションを作成したいと考えています。このアプリケーションは、OpenEJB と WebLogic 10.3 の両方で実行できます。EJB は両方とも EJB 3.0 です。

OpenEJB と WebLogic の両方で実装する方法は知っていますが、同じコードを使用して両方の環境にデプロイしたいという問題があります。WebLogic の Context.INITIAL_CONTEXT_FACTORY は weblogic.jndi.WLInitialContextFactory ですが、OpenEJB はそうではないため、問題は JNDI ルックアップの方法だと思います。

現在の考えでは、最初の EJB はサービス ロケータを使用して 2 番目の EJB をルックアップし、サービス ロケータは 2 つの環境で異なる INI を読み取ります。他の提案はありますか?注釈を使用するだけで、外部 INI ファイルを使用する必要がない解決策はありますか。

2 つの EJB は 1 つのコンテナーに存在しますが、将来、一方が別のコンテナーに移動する可能性があります。

2011/10/06 更新

デビッドの提案で、私はいくつかの変更を加えました。コードは JUnit コードではなく POJO です。@LocalClient と initialContext.bind("inject", this); は使用しません。(JUnitコードに2つのコードを入れました)

  1. resources\META-INF\application-client.xml を配置 ( のみを含む)

  2. リソース\jndi.properties を配置

    jdbc/OrderDB = new://Resource?type=DataSource
    jdbc/OrderDB.JdbcDriver = oracle.jdbc.OracleDriver
    jdbc/OrderDB.JdbcUrl = jdbc:oracle:thin:@*.*.*.*:1521:test
    jdbc/OrderDB.JtaManaged = false
    jdbc/OrderDB.UserName = test
    jdbc/OrderDB.Password = test
    
  3. 参照コード

    InitialContext ctx= new InitialContext();
    ctx.lookup("jdbc/" + name);
    

以下はログです。OpenEJB はデータベースの JNDI を作成します。また、Eclipse デバッグ モードを使用して「ctx」の内容を確認し、MyProps で「jdbc/OrderDB」を見つけます。

INFO - Configuring Service(id=jdbc/OrderDB, type=Resource, provider-id=Default JDBC Database)

しかし、最終的にはまだ検索できません。私も ctx.lookup(name), ctx.lookup("java:comp/env/jdbc/" + name) を使用しようとしましたが、結果は同じです。

javax.naming.NameNotFoundException: Name "jdbc/OrderDB" not found.

2011/10/12更新

Java EE6より前のDavidのコメントに基づいて、唯一の解決策は、サービスロケーターといくつかの構成を使用して、WebLogicとOpenEJBの間で異なるJNDIを使用することだと思います。以下はテスト結果です。

DB: WebLogic: OrderDB、OpenEJB: openejb:Resource/jdbc/OrderDB

トランザクション マネージャ: WebLogic: javax.transaction.TransactionManager、OpenEJB: java:comp/TransactionManager

EJB : どちらも接頭辞なしで EJB 名を検索するだけです

4

3 に答える 3

2

更新の質問は非常に異なる質問であるため、別の回答を投稿してください。

Java EE 6 より前のグローバル JNDI なし

要するに、Java EE 6 より前のバージョンでは、グローバル JNDI はありません。したがって、「 xJNDI 名は何ですか」という質問は、文字通り、答えられない質問です。各 EJB には独自のプライベート JNDI 名前空間があり、「POJO」には名前空間がまったくありません。それらは、それを呼び出した EJB の JNDI 名前空間を使用します。したがって、「java:comp/env/myDataSource」をできるだけグローバルに表示するには、アプリケーション内のすべての EJB に対してその参照を宣言する必要があります。

これによりユーザーが作成する構成作業の量は、非常に壊滅的です。java:moduleJava EE 6 では、ついにグローバル JNDI と 3 つの新しい標準名前空間 と が導入java:appされjava:globalました。Java EE 6 より前に存在するグローバル JNDI 機能はすべてベンダー固有であり、移植性がありません。

指定された名前に対して OpenEJB でグローバル JNDI ルックアップを実行するためのベンダー固有で移植性のない方法は、ルックアップすることです。openejb:Resource/jdbc/OrderDB

スペードをスペードと呼ぶ

OpenEJB では、一部のベンダーが行っているようjdbc/OrderDBな非標準のルックアップを意図的にサポートしていません。java:jdbc/OrderDBOpenEJB のグローバル名に必要なプレフィックスはopenejb:.

JNDI は複雑で紛らわしいので、移植不可能な名前を移植可能な名前のように見せても、ユーザーにとって何のメリットもありません。特定の命名スタイルが移植可能ではなく、ベンダー ロックインを作成する場合は、そのように見える必要があります。したがって、openejb:接頭辞を使用すると、グローバルに必要なものにアクセスできますが、実行していることは移植性がなく、変更なしで他のプラットフォームで動作することを期待すべきではないことは少なくとも明らかです.

于 2011-10-08T23:33:04.263 に答える
1

jndi.properties通常はプロパティとして渡される構成の 100% を外部化するために使用できる標準ファイルがあることに注意してくださいIntitialContext

サービス ロケーター パターンを使用すると、コードの見栄えが良くなり、保守が容易になる可能性がありますが、実際のサーバー接続情報は簡単に外部化できます。

jndi.propertiesファイルがルートのクライアントのクラスパス上にあることを確認する必要があります (つまり、META-INFディレクトリ内ではありません)。はそれIntialContextを見つけてロードします。コンストラクターに渡されたプロパティはIntialContext、経由で渡されたものを単純にオーバーライドします。jndi.properties

OpenEJB 側では、WebLogic 形式と一致するようにJNDI 名の形式を変更できる必要があります。そうでない場合はお知らせください。欠落しているメタデータをフォーマッタに追加して、正確に一致させることができます。

于 2011-09-26T20:02:58.987 に答える
0

デフォルトのコンテキストだけを使用することはできませんか?次に、特定の実装を指定する必要はなく、標準参照を介してルックアップを実行できます。

それ以外の場合は、実行時にコンテキストの詳細を決定するための何らかのプロパティファイルが残っていると思います。

于 2011-09-20T16:25:15.107 に答える