jBoss deployment of message-driven bean spec violation

人走茶凉 提交于 2020-01-15 18:14:22

问题


I have an java EE application which has one message-driven bean and it runs fine on JBoss 4, however when I configure the project for JBoss 6 and deploy on it, I get this error;

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.

But my bean HAS the onMessage method! It would not have worked on jboss 4 either then.

Why do I get this error!?

Edit:

The class in question looks like this

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 }
}
}

Edit 2: And this is the jboss.xml relevant parts

<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>

Edit 3:

I just removed all my jars from the project, and only re-added relevant ones (from new versions also) to put out NoClassDefFound errors. Still the problem remains.

Edit: Any directions, what area should I look at? My project, or jboss-configration, or the deployment settings??


回答1:


org.jboss.ejb.deployers.EjbDeployer.verifier

looks for

public void onMessage(javax.jms.Message)

via some code like this (this is from 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;
    }

It is important that the parameter type is javax.jms.Message and nothing else, for example some subclass or superclass or some implementing class.

Your signature is public void onMessage(Message message) which looks ok on first sight.

A Class is equal only in its ClassLoader. If for some reasons javax.jms.Message is available in different classloaders in the same JVM, strange things can happen, depending on the ClassLoader of the EjbDeployer.verifier. Maybe the EjbDeployer.verifer has a access to javax.jms.Message in another ClassLoader as MyMDB. As result, both javax.jms.Message are not equal to each other, although they are the same byte-code and literally exists. The EjbVerifier will warn about missing onMessage, because javax.jms.Message on ClassLoader A is not equal to javax.jms.Message on ClassLoader B.

This can happen when libraries with javax.jms.Message is copied on wrong places on the JBoss AS. So I guess - from a distance - that there is some jars containing javax.jms.Message in wrong places on the JBoss or the EAR. For example some wrong jbossallclient.jar in the EAR.




回答2:


Make sure your EAR does not contain its own copies of the javax.ejb classes (or any javax classes at all, for that matter). JBoss 4 and 6 have rather different classloading semantics, and what works on one may not work on the other. For example, if your EAR's lib contained its own copies of Message or MessageListener, then it may no longer work.




回答3:


I tried it out on "JBossAS [6.0.0.20100911-M5 "Neo"]" and 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
    }
}

And this setting works. Do you have the same imports for your bean (perhaps there was an automatic import gone wrong???)



来源:https://stackoverflow.com/questions/4461821/jboss-deployment-of-message-driven-bean-spec-violation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!