1

我有一个 java EE 应用程序,它有一个消息驱动 bean,它在 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尽管它们是相同的字节码并且确实存在,但两者并不相等。EjbVerifier 将警告 missing onMessage,因为javax.jms.MessageClassLoader A 上不等于javax.jms.MessageClassLoader B 上。

当库javax.jms.Message被复制到 JBoss AS 上的错误位置时,可能会发生这种情况。javax.jms.Message所以我猜 - 从远处看 -在 JBoss 或 EAR 上的错误位置包含一些罐子。例如 EAR 中的一些错误 jbossallclient.jar。

于 2010-12-27T21:10:40.403 回答
1

确保您的 EAR 不包含其自己的javax.ejb类副本(或任何javax类,就此而言)。JBoss 4 和 6 具有相当不同的类加载语义,适用于一个的可能不适用于另一个。例如,如果您的 EARlib包含自己的Messageor副本MessageListener,那么它可能不再起作用。

于 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 回答