1

1 つのメッセージ駆動型 Bean を持つ Java EE アプリケーションがあり、JBoss 4 では正常に動作しますが、JBoss 6 用にプロジェクトを構成してデプロイすると、このエラーが発生します。

WARN  [org.jboss.ejb.deployers.EjbDeployer.verifier] EJB spec violation:

...

The message driven bean must declare one onMessage() method.

...

org.jboss.deployers.spi.DeploymentException: Verification of Enterprise Beans failed, see above for error messages.

しかし、私の Bean には onMessage メソッドがあります。その場合、jboss 4 でも機能しませんでした。

なぜこのエラーが発生するのですか!?

編集:

問題のクラスは次のようになります

package ...
imports ...

public class MyMDB implements MessageDrivenBean, MessageListener {
AnotherSessionBean a;
OneMoreSessionBean b;

public MyMDB() {}

public void onMessage(Message message) {
    if (message instanceof TextMessage) {
        try {
                //Lookup sessionBeans by jndi, create them
                lookupABean();
                // check message-type, then invokie
                a.handle(message);
                // else
                b.handle(message);

            } catch (SomeException e) { 
                  //handling it 
            } 
     }
}

public void lookupABean() {
    try {
         // code to lookup session beans and create.
    } catch (CreateException e) { // handling it and catching NamingException too }
}
}

編集2: これはjboss.xmlの関連部分です

<message-driven>
<ejb-name>MyMDB</ejb-name>
<destination-jndi-name>topic/A_Topic</destination-jndi-name>
<local-jndi-name>A_Topic</local-jndi-name>
<mdb-user>user</mdb-user>
<mdb-passwd>pass</mdb-passwd>
<mdb-client-id>MyMessageBean</mdb-client-id>
<mdb-subscription-id>subid</mdb-subscription-id>
<resource-ref>
<res-ref-name>jms/TopicFactory</res-ref-name>
<jndi-name>jms/TopicFactory</jndi-name>
</resource-ref>
</message-driven>

編集3:

プロジェクトからすべての jar を削除し、関連するものだけを (新しいバージョンからも) 再追加して、NoClassDefFound エラーを出しました。それでも問題は残ります。

編集: 道順、どのエリアを見るべきですか?私のプロジェクト、または jboss-configration、またはデプロイメント設定??

4

3 に答える 3

2

org.jboss.ejb.deployers.EjbDeployer.verifier

探す

public void onMessage(javax.jms.Message)

次のようなコードを介して (これは JBoss5 からのものです):

    /**
     * Check if the given message is the onMessage() method
     */
    public boolean isOnMessageMethod(Method m)
     {
       if ("onMessage".equals(m.getName()))
       {
          Class[] paramTypes = m.getParameterTypes();
          if (paramTypes.length == 1)
          {
             if (Message.class.equals(paramTypes[0]))
                return true;
          }
       }
       return false;
    }

javax.jms.Messageサブクラスやスーパークラス、または実装クラスなど、パラメーターの型が であることが重要です。

あなたの署名はpublic void onMessage(Message message)、一見問題ないように見えます。

AClassは、その でのみ等しいClassLoaderです。何らかの理由javax.jms.Messageで同じ JVM 内の異なるクラスローダーで使用できる場合、EjbDeployer.verifier の ClassLoader によっては、奇妙なことが起こる可能性があります。たぶん、EjbDeployer.verifer はjavax.jms.Message別の ClassLoader にアクセスできますMyMDB。結果として、両者javax.jms.Messageは同じバイトコードで文字通り存在しますが、互いに等しくありません。ClassLoader Aでは ClassLoader Bと等しくないonMessageため、EjbVerifier は欠落について警告します。javax.jms.Messagejavax.jms.Message

これは、ライブラリがjavax.jms.MessageJBoss AS の間違った場所にコピーされた場合に発生する可能性があります。javax.jms.Messageしたがって、JBoss または EAR の間違った場所に含まれている jar がいくつかあると、遠くから推測します。たとえば、EAR 内の間違った jbossallclient.jar があります。

于 2010-12-27T21:10:40.403 に答える
1

EAR に独自のjavax.ejbクラスのコピーが含まれていないことを確認してください (さらに言えば、どのjavaxクラスも含まれていません)。JBoss 4 と 6 はかなり異なるクラスローディング セマンティクスを持ち、一方で機能するものは他方では機能しない場合があります。たとえば、EARにまたはlibの独自のコピーが含まれている場合、それは機能しなくなる可能性があります。MessageMessageListener

于 2010-12-16T14:36:28.120 に答える
1

「JBossAS [6.0.0.20100911-M5 "Neo"]」とEclipse Heliosで試してみました

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;
import javax.jms.Message;
import javax.jms.MessageListener;

@MessageDriven(
    activationConfig = { @ActivationConfigProperty(
            propertyName = "destinationType", propertyValue = "javax.jms.Topic"
    ) }, 
    mappedName = "topic/A_Topic", 
    messageListenerInterface = MessageListener.class)
public class MyMDB implements MessageListener, MessageDrivenBean {

    private static final long serialVersionUID = -4923389997501209506L;

    public MyMDB() {
        // TODO Auto-generated constructor stub
    }
    @Override
    public void ejbRemove() {
        // TODO Auto-generated method stub
    }
    @Override
    public void setMessageDrivenContext(MessageDrivenContext arg0) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onMessage(Message message) {
        // TODO Auto-generated method stub
    }
}

そして、この設定は機能します。Bean に同じインポートがありますか (おそらく、自動インポートが間違っていたのでしょうか???)

于 2010-12-27T15:26:55.627 に答える