web-dev-qa-db-ja.com

NamingExceptionでejbルックアップが失敗する

Web.xmlに以下を追加しました。

<ejb-ref>
        <ejb-ref-name>ejb/userManagerBean</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <home>gha.ywk.name.entry.ejb.usermanager.UserManagerHome</home>
        <remote>what should go here??</remote>
</ejb-ref>

次のJavaコードはNamingExceptionを与えています:

public UserManager getUserManager () throws HUDException {
    String ROLE_JNDI_NAME = "ejb/userManagerBean";
    try {
        Properties props = System.getProperties();
        Context ctx = new InitialContext(props);
        UserManagerHome userHome = (UserManagerHome) ctx.lookup(ROLE_JNDI_NAME);
        UserManager userManager = userHome.create();
        WASSSecurity user = userManager.getUserProfile("user101", null);
        return userManager;
    } catch (NamingException e) {
        log.error("Error Occured while getting EJB UserManager" + e);
        return null;
    } catch (RemoteException ex) {
        log.error("Error Occured while getting EJB UserManager" + ex);
        return null;
    } catch (CreateException ex) {
        log.error("Error Occured while getting EJB UserManager" + ex);
        return null;
    }
}

コードはコンテナ内で使用されます。つまり、.WARがサーバー(Sun Application Server)にデプロイされているということです。

StackTrace(jsightの提案の後):

>Exception occurred in target VM: com.Sun.enterprise.naming.Java.javaURLContext.<init>(Ljava/util/Hashtable;Lcom/Sun/enterprise/naming/NamingManagerImpl;)V 
Java.lang.NoSuchMethodError: com.Sun.enterprise.naming.Java.javaURLContext.<init>(Ljava/util/Hashtable;Lcom/Sun/enterprise/naming/NamingManagerImpl;)V
 at com.Sun.enterprise.naming.Java.javaURLContextFactory.getObjectInstance(javaURLContextFactory.Java:32)
 at javax.naming.spi.NamingManager.getURLObject(NamingManager.Java:584)
 at javax.naming.spi.NamingManager.getURLContext(NamingManager.Java:533)
 at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.Java:279)
 at javax.naming.InitialContext.lookup(InitialContext.Java:351)
 at gov.hud.pih.eiv.web.EjbClient.EjbClient.getUserManager(EjbClient.Java:34)
11
Drake

Sun Application ServerのWebアプリケーションからEJBアプリケーション(EJBモジュールと呼ばれます)にアクセスしたいと思いますよね?

わかりました、行きましょう。

EJBをアプリケーションサーバーにデプロイすると、アプリケーションサーバーはそれにアクセスする方法としてアドレス(グローバルJNDIアドレスと呼ばれる)を与えます(アドレスなど)。アプリケーションサーバーから別のサーバーに変わります。

JBoss Application Serverでは、グローバルJNDIアドレス(起動後)を次のアドレスで確認できます。

http://127.0.0.1:8080/jmx-console/HtmlAdaptor

Sun Application Serverで、(起動後に)グローバルJNDIアドレスを表示する場合は、次の手順を実行します。

次のアドレスの管理コンソールにアクセスします

http://127.0.0.1:4848/asadmin

そして、JNDIブラウジングをクリックします

EJB ISすぐに登録されていない場合は、何か問題があります

EJBには、EJB2.1とEJB3.0の2つの種類があります。では、違いは何ですか?

まあ、まあ、まあ...

EJB2.1から始めましょう

  1. ホームインターフェースを作成する

これは、ローカルまたはリモートのEJBオブジェクトを作成、破棄、および検索するためのメソッドを定義します。これは、EJBオブジェクトのライフサイクルインターフェイスとして機能します。すべてのホームインターフェースは、標準インターフェースjavax.ejb.EJBHome(リモートejbオブジェクトを使用している場合)またはjavax.ejb.EJBLocalHome(ローカルEJBオブジェクトを使用している場合)を拡張する必要があります。

// a remote EJB object - extends javax.ejb.EJBHome
// a local EJB object - extends javax.ejb.EJBLocalHome
public interface MyBeanRemoteHome extends javax.ejb.EJBHome {

    MyBeanRemote create() throws javax.ejb.CreateException, Java.rmi.RemoteException;

}

Application Serverは、EJBオブジェクトを取得する方法としてHomeオブジェクトを作成します。

次のことに注意してください

セッションBeanのリモートホームインターフェイスは、1つの<METHOD>メソッドを定義する必要がありますOR MORE create <METHOD>メソッド。ステートレスセッションBeanは、引数なしで1つの<METHOD>メソッドを定義する必要があります。

.。

throws句にはjavax.ejb.CreateExceptionを含める必要があります

.。

ホームインターフェースがjavax.ejb.EJBHomeを拡張する場合、throws句にはJava.rmi.RemoteExceptionを含める必要があります。 javax.ejb.EJBLocalHomeを拡張する場合は、Java.rmi.RemoteExceptionを含めないでください。

.。

ステートフルセッションBeanの各createメソッドにはcreate <METHOD>という名前を付ける必要があり、セッションBeanクラスで定義されているInitメソッドまたはejbCreate <METHOD>メソッドのいずれかと一致する必要があります。一致するejbCreate <METHOD>メソッドは、同じ数とタイプの引数を持っている必要があります。ステートレスセッションBeanのcreateメソッドには名前を付ける必要がありますcreateが、一致する「ejbCreate」メソッドを持つ必要はありません。


次に、EJBオブジェクトでビジネスロジックを定義するためのビジネスインターフェイスを作成します

// a remote EJB object - extends javax.ejb.EJBObject
// a local EJB object - extends javax.ejb.EJBLocalObject
public interface MyBeanRemote extends javax.ejb.EJBObject {

    void doSomething() throws Java.rmi.RemoteException;

}

今、次の世話をします

リモートEJBオブジェクトを使用している場合、リモートインターフェイスメソッドはローカルインターフェイスタイプまたはローカルホームインターフェイスタイプを公開してはなりません(MUSTNOT)。

.。

ホームインターフェースがjavax.ejb.EJBObjectを拡張する場合、throws句にはJava.rmi.RemoteExceptionを含める必要があります。 javax.ejb.EJBLocalObjectを拡張する場合は、Java.rmi.RemoteExceptionを含めないでください。


今私たちのEJB

public class MyBean implements javax.ejb.SessionBean {

    // why create method ? Take a special look at EJB Home details (above)
    public void create() {
        System.out.println("create");
    }

    public void doSomething() throws Java.rmi.RemoteException {
        // some code
    };

}

今、次の世話をします

Javax.ejb.SessionBeanを実装する必要があります。これは、4つのメソッドを定義します-上記には示されていません:setSessionContext、ejbRemove、ejbPassivate、およびejbActivate。

Beanに注意してください実装しません EJB仕様のため、ビジネスインターフェイスには次のように記載されています。

インターフェイスで定義されたメソッドごとに、セッションBeanのクラスに一致するメソッドが必要があります。マッチング方法には次のものが必要です。

  • 同じ名前
  • 同じ数とタイプの引数、および同じ戻り値の型。
  • セッションBeanクラスのmatchingメソッドのthrows句で定義されているすべての例外は、ローカルインターフェイスのメソッドのthrows句で定義されている必要があります。

そして、に従ってejb-jar.xmlファイルを宣言する必要があります

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://Java.Sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://Java.Sun.com/xml/ns/j2ee http://Java.Sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" version="2.1">
    <enterprise-beans>
        <session>
            <ejb-name>HelloWorldEJB</ejb-name>
            <home>br.com.MyBeanRemoteHome</home>
            <remote>br.com.MyBeanRemote</remote>
            <local-home>br.com.MyBeanLocalHome</local-home>
            <local>br.com.MyBeanLocal</local>
            <ejb-class>br.com.MyBean</ejb-class>
            <session-type>Stateless</session-type>
            <transaction-type>Container</transaction-type>
        </session>
    </enterprise-beans>
</ejb-jar>

ローカルEJBオブジェクトがない場合は、上記のデプロイメント記述子から削除してください

<local-home>br.com.MyBeanLocalHome</local-home>
<local>br.com.MyBeanLocal</local>

リモートEJBオブジェクトがない場合は、上記のデプロイメント記述子から削除してください

<home>br.com.MyBeanRemoteHome</home>
<remote>br.com.MyBeanRemote</remote>

そしてMETA-INFディレクトリに入れます

Jarファイルには次のものが含まれます

/META-INF/ejb-jar.xml
br.com.MyBean.class
br.com.MyBeanRemote.class
br.com.MyBeanRemoteHome.class

今、私たちのEJB 3.0

// or @Local
// You can not put @Remote and @Local at the same time
@Remote
public interface MyBean {

    void doSomething();

}

@Stateless
public class MyBeanStateless implements MyBean {

    public void doSomething() {

    }

}

他には何もありません

JBossにjarファイルを入れます

<JBOSS_HOME>/server/default/deploy

Sun Application Serverアクセス​​(起動後)管理コンソール

http://127.0.0.1:4848/asadmin

そして、ejb-jarファイルをデプロイするためにEJBモジュールにアクセスします

NetBeansにアプリケーションをデプロイするときに問題が発生するため、次のことをお勧めします。

  1. 単純なJavaライブラリPROJECT(メインメソッドのない単純なjar)を作成します
  2. / server/default/lib(EJBを取得するためのjarファイルを含む)jarファイルをJavaアプリケーションにJBossを使用しているかどうかに関係なく追加します(Sun Application Serverのどのディレクトリかわかりません)
  3. 上記のコードを実装する

今度は別の戦争プロジェクトを作成します

  1. 上で作成したプロジェクトを追加し、<JBOSS_HOME>/clientを追加します(EJBにアクセスするためのjarファイルが含まれています)。繰り返しますが、Sun ApplicationServerのどのディレクトリかわかりません。そのドキュメントをチェックアウトします。
  2. 回答の上部に示されているグローバルマッピングアドレスを参照してください

そして、JBossを使用しているかどうかに関係なく、サーブレットまたはその他のコードに次のコードを実装します。

public static Context getInitialContext() throws javax.naming.NamingException {

    Properties p = new Properties();
    p.put(Context.INITIAL_CONTEXT_FACTORY,        "org.jnp.interfaces.NamingContextFactory");
    p.put(Context.URL_PKG_PREFIXES, " org.jboss.naming:org.jnp.interfaces");
    p.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");

    return new javax.naming.InitialContext(p);
}

または、Sun Application Serverを使用しているかどうかにかかわらず、次のようにします-ファイルappserv-rt.jar(Sun Application Serverにappserv-rt.jarが含まれている過去はわかりません)をクラスパスに入れます

public static Context getInitialContext() throws javax.naming.NamingException {

    return new javax.naming.InitialContext();

}

サーブレットなどでEJBにアクセスするため

MyBeanRemote myBean = (MyBeanRemote) getInitialContext().lookup(<PUT_EJB_GLOBAL_ADDRESS_RIGHT_HERE>);

myBean.doSomething();

よろしく、

37
Arthur Ronald

まず、web.xmlを修正し、それにリモートインターフェイスを追加します。

_<ejb-ref>
  <description>Sample EJB</description>
  <ejb-ref-name>SampleBean</ejb-ref-name>
  <ejb-ref-type>Session</ejb-ref-type>
  <home>com.SampleHome</home>
  <remote>com.Sample</remote> <!-- the remote interface goes here -->
</ejb-ref>
_

次に、_Java.lang.NoSuchMethodError_に関して、Seanは正しいですが、NetBeans内で使用しているアプリサーバー「クライアントライブラリ」のバージョンとアプリサーバーのバージョン(サーバー側)が一致していません。ただし、どのJARを調整する必要があるかを正確に伝えることはできません。SunApplicationServerのドキュメントを参照してください。

PS:これは問題への直接の答えではありませんが、System.getProperties()の呼び出しの結果を使用して初期コンテキストを作成するときに、現在有用なプロパティを渡していないと思います。これらのプロパティは、コンテキストの環境を定義します(たとえば、初期コンテキストファクトリ)。詳細については、 InitialContext javadocsを参照してください。

1
Pascal Thivent

最後の2つの答えは、変更/修正する必要があるという点でどちらも正しいです。しかし、表示されるNoSuchMethodErrorは、コードからのものでも、コードを見つけようとしているものからのものでもありません(この場合、ある種のNoClassDefFoundExceptionが生成されると思います)。これは、コンテナによって提供されるJNDIプロバイダーの互換性のないバージョンのように見え、JavaライブラリのJNDI実装が望んでいるものです。これはかなり漠然とした答えですが、おそらくそれが解決できると想像します。アプリケーションサーバーをアップグレードし、JNDIに関連するインフラストラクチャクラスの古いコピーをアプリにデプロイしないようにします。これにより、干渉が発生する可能性があります。

1
Sean Owen