jBoss部署消息驱动的bean规范违规

时间:2010-12-16 14:33:13

标签: deployment jboss jboss-mdb message-driven-bean

我有一个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,还是部署设置?

3 个答案:

答案 0 :(得分: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),第一眼就看起来不错了。

Class仅在其ClassLoader中相等。如果由于某些原因javax.jms.Message在同一JVM中的不同类加载器中可用,则可能会发生奇怪的事情,具体取决于EjbDeployer.verifier的ClassLoader。也许EjbDeployer.verifer可以访问另一个ClassLoader中的javax.jms.Message MyMDB。结果,两个javax.jms.Message彼此不相等,尽管它们是相同的字节码并且确实存在。 EjbVerifier将警告错过onMessage,因为ClassLoader A上的javax.jms.Message在ClassLoader B上不等于javax.jms.Message

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

答案 1 :(得分:1)

确保您的EAR不包含自己的javax.ejb类(或任何javax类的副本)(就此而言)。 JBoss 4和6具有相当不同的类加载语义,并且在一个上工作的东西可能在另一个上不起作用。例如,如果您的EAR lib包含自己的MessageMessageListener副本,则可能不再有效。

答案 2 :(得分: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有相同的导入(可能是自动导入出错了吗?)