2011-12-09 9 views
1

私はJava EE 6に大きなWebプロジェクトを持っています。通常のJavaクラスでのEJBの使用。ステートレスなEJBをインスタンス化しようとしています

ここでは、Twitter情報を取得して文字列を返す新しいクラスを追加します。これまでのところ、文字列はTwitterからJSONファイルから抽出され、私のデータベースに永続化される準備が整いました。私の問題は、通常、すべてのデータベース呼び出しを処理するEJBから情報を渡す方法がわかりません。私はJPAを使用しており、そのマネージャはすべてのデータベースアクセスを持つDAOクラスを持っています。私はすでにupdateDatabase(String)のためのメソッドを持っています。私は追加する文字列を持つクラスからupdateDatabase(String)を呼び出すことができるようにしたいと思いますが、そのようなステートレスBeanをインスタンス化するための良いフォームかどうかわかりません。通常は、Beanを挿入し、そのメソッドにアクセスするためにクラス名だけを呼び出します。私は、おそらく、EJBの内部からクラスを生成するtwitter文字列を参照してみることもできますが、そこでインスタンス化してmain()メソッド呼び出しを実行して実行する必要があります。私は本当にこれを行う方法がわかりません。今、私のTwitterの消費クラスは、mainメソッドを持つ単なるPOJOです。何らかの理由で、ライブラリメソッドのいくつかが、IOUtils()APIのメインインターフェイスの外部で動作しなかったため、「インスタンスは標準プログラミングでは構築しない」と直接言います。

私はPOJOがJava EEプロジェクトにどのように「混在しているか」を尋ねています。ほとんどの場合、クラスはEJBとサーブレットです。

編集:再読した後、上記のことがわかりにくいように見えるので、私はそれを簡素化しようとします。基本的に私はメインメソッドを持つクラスを持っています。データベースアクセスを扱うEJBクラスを呼び出して、updateDatabase(String)というメソッドを呼び出し、文字列を渡すだけです。私はこれをどのようにするべきですか?

編集:EJBを直接インスタンス化するのではなく、JNDIルックアップとサブシーケンス参照のように見えますか?

編集:これらのクラスはすべて同じWebプロジェクト内にあります。同じパッケージ内にあります。私は1つを注入するか、POJOをEJBに変換することができました。しかし、POJOにはmainメソッドがあり、ライブラリファイルのいくつかはインスタンス化されたくないので、メインで実行するのが最良の選択肢のようです。

私のメインのコード:

public class Driver { 

    @EJB 
    static RSSbean rssbean; 

    public static void main(String[] args) throws Exception { 

     System.setProperty("http.proxyHost", "proxya..com"); 
     System.setProperty("http.proxyPort", "8080"); 
     /////////////auth code///////////////auth code///////////////// 
     String username = System.getProperty("proxy.authentication.username"); 
     String password = System.getProperty("proxy.authentication.password"); 
     if (username == null) { 
      Authenticator.setDefault(new ProxyAuthenticator("", "")); 
     } 
     ///////////////end auth code/////////////////////////////////end 

     URL twitterSource = new URL("http://search.twitter.com/search.json?q=google"); 
     ByteArrayOutputStream urlOutputStream = new ByteArrayOutputStream(); 

     IOUtils.copy(twitterSource.openStream(), urlOutputStream); 
     String urlContents = urlOutputStream.toString(); 
     JSONObject thisobject = new JSONObject(urlContents); 
     JSONArray names = thisobject.names(); 
     JSONArray asArray = thisobject.toJSONArray(names); 
     JSONArray resultsArray = thisobject.getJSONArray("results"); 
     JSONObject(urlContents.substring(urlContents.indexOf('s')));     
     JSONObject jsonObject = resultsArray.getJSONObject(0); 

     String twitterText = jsonObject.getString("text");   
     rssbean.updateDatabase("twitterText"); 
    } 
} 

私もrssbean.updateDatabase("twitterText");

+1

あなたはEJBのインスタンスを作成しません。これまでそれはコンニナーが扱うものです。一方、あなたができることは、メソッドにPostConstructアノテーションを入れて(コンストラクタの代わりに)何かを実行することですが、それはあなたの問題とは関係ありません。 –

+1

その理由は、そのEJBがnullである理由はおそらくドライバクラスはコンテナ管理クラスではありません。これは、Driverクラスがアプリケーション・エントリー・ポイント・クラス(静的フィールドにEJBを挿入できる唯一の方法)である場合にのみ有効です。しかし、あなたはこれがWebアプリケーションだと言っています。では、どこからDriver.main()を呼び出しますか?とにかく、静的メソッド(エントリポイントでないと仮定して)にそのコードを本当に必要とする場合、JNDIルックアップか、ファクトリパターンの周りのコードをリファクタリングしてインスタンスまたは何かをそれらの行に挿入します。 –

+0

私は操作をテストする方法としてmainメソッドを使用していました。私は必ずしもウェブアプリケーションのためにそれを必要としません。 URLからデータを取得してデータベースに追加する操作をトリガするためにどのようなメカニズムを使用するのかはわかりませんが。私はそのために何らかの自動実行が必要です。 – Randnum

答えて

1

ステートレスEJBとしてPOJOを使用して周りのどこかにjava.lang.NullPointerExceptionを取得しています、そのアプローチには何の問題もありません。

ウィキペディアから:EJBは、アプリケーションのビジネスロジックをカプセル化するサーバーサイドモデルです。

POJOクラスはWebサービスを使用するため、ビジネスロジックを実行します。

EDIT>あなたのコメントを読んで、Java EEコンテナの外部からEJBにアクセスしようとしていますか? EJBを別のEJBに挿入することができます(両方ともステートレスでなければなりません)

+0

彼らは同じプロジェクトにいません。実際には同じパッケージ内にあります。ただ一つはEJBであり、もう一つはこの独立したtwitter操作を行うための標準POJOです。私はこれをEJBとすることについては考えていませんでしたが、どこから呼び出すのですか。私はメインクラスを削除しなければならないでしょうか? – Randnum

+0

私はまだ、その主要な方法が理解できません。どちらの方法でもEJBを注入できます。それは本当にあなたのTwitterのpojo上のメソッドが呼び出されるところから来ています。あなたは@Inject daoClassをTwitter beanに入れ、そのメソッドを呼び出すことができます –

+0

ああ、申し訳ありませんが、メインのクラスがあります。それはTwitterクラスを呼び出しますか?もしそうなら、私はTwitterクラスのEJBをメインクラスに挿入します。そして、あなたのDAOをTwitterやMainに挿入するか、あなたのソフトウェアアーキテクチャに依存します。とにかく、私はこれでどこに行くのか分かります。 –

6

InitialContext#lookupメソッドを使用して、アプリケーションサーバーからEJB参照を取得する必要があります。たとえば
:しかし

@Stateless(name="myEJB") 
public class MyEJB { 

    public void ejbMethod() { 
    // business logic 
    } 

} 

public class TestEJB { 

    public static void main() { 
    MyEJB ejbRef = (MyEJB) new InitialContext().lookup("java:comp/env/myEJB"); 
    ejbRef.ejbMethod(); 
    } 
} 

は、ルックアップに使用するEJB名は、ベンダー固有であってもよいことに注意してください。また、EJB 3。1は、すべてのアプリケーションサーバーで動作するはずのportable JNDI namesのアイデアを紹介しています。

+0

ありがとう、JNDIルックアップは私がまだ使用していないことの一つです。アノテーション付きのJEE6では、作業がずっと楽になります。私がしたのは、EJBの静的インスタンスを作成し、そのインスタンスでメソッドを呼び出すことでした。これをするのは間違っていると感じますが、理由はわかりません。 – Randnum

+0

驚くばかりの答え! –

1

EJBにアクセスしたいスタンドアロンプ​​ログラムがある場合は、いくつかのオプションがあります。

1つは、JNDIを使用してEJBをルックアップすることです。 EJBにはリモート・インタフェースが必要で、JNDIパーツをコンテナとして構成するだけでなく、スタンドアロン・アプリケーション内に特定のコンテナ・ジャーを組み込む必要があります。

もう1つの手法は、「アプリケーションクライアント」として知られるJava EE成果物を使用することです。ここには、クラスのコンテナプロバイダラッパーがありますが、コンテナ内でクラスを実行するのと非常によく似た実行時環境を提供します。特に、EJBインジェクションなどのものがあります。

あなたはまだ別のJVMで実行されているので、リモートEJBを参照する必要がありますが、アプリケーションクライアントコンテナはアプリケーションをサーバーに接続する際にボイラープレートの束を処理します。 Java EE成果物は、アプリケーションクライアントアプリケーションを設定して起動する方法にもコンテナによって異なります。

最後に、コンテナ内に配置されたPOJOとは対照的に、POJOがEJBコンテナとこのようにやり取りする方法には基本的に少しの違いがあります。このインタフェースは依然としてEJBの注入(以前よりもJava EE 6で簡単に実行)やJNDI経由の参照を参照するための問題です。唯一の重要な違いは、コンテナに配備されたPOJOがリモートの代わりにローカルインタフェースを使用できることです。

+0

彼らは実際には同じWebプロジェクトに入っています。別のEJBを作成し、それを通常のpojoとして残し、他のEJBをインスタンス化し、他のクラスから参照する必要があるかどうかは不思議でした。それとも、どうやって互いを参照できるようにするか。 – Randnum

+0

トランザクション機能やその他のEJBライフサイクル/インターセプタ機能が必要ない場合は、POJOにして移動してください。 EJBは特に高価なものでも、それ以外のものでもありません。しかし、「新しいTweetPojo()」がその仕事をするときには、ちょうどそのことに行きます。 –

+0

わかりました。私はちょうどデータベースにそれを取得し、それを行うには、私はデータベースアクセスのためのメソッドを含むEJBを介して行く必要はありません。他のクラスとサーブレットはこのEJBを使用するので、私はPOJOに変換することはできません。 – Randnum

関連する問題