Domanda

Ho un'applicazione Java EE che ha un bean message-driven e funziona bene su JBoss 4, tuttavia quando a configurare il progetto per JBoss 6 e implementare su di esso, ottengo questo errore;

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.

Ma la mia Bean ha il metodo onMessage! Non avrebbe funzionato su JBoss 4 né allora.

Perché ricevo questo errore!?

Modifica

La classe negli sguardi interrogativi come questo

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

Modifica 2: E questo è pertinenti parti 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>

Modifica 3:

Ho appena tolto tutti i miei vasi dal progetto, e solo re-ha aggiunto quelli rilevanti (da nuove versioni anche) per mettere fuori NoClassDefFound errori. Ancora il problema rimane.

Modifica Eventuali indicazioni, quale area dovrei guardare? Il mio progetto, o jboss-configration, o impostazioni di distribuzione ??

È stato utile?

Soluzione

org.jboss.ejb.deployers.EjbDeployer.verifier

sguardi per

public void onMessage(javax.jms.Message)

tramite un codice come questo (questo è da 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;
    }

E 'importante che il tipo di parametro è javax.jms.Message e nient'altro, per esempio qualche sottoclasse o superclasse o qualche classe di implementazione.

La tua firma è public void onMessage(Message message) che sembra ok a prima vista.

Un Class è pari solo nella sua ClassLoader. Se per qualche motivo javax.jms.Message è disponibile in diversi classloader nella stessa JVM, cose strane possono accadere, a seconda della ClassLoader della EjbDeployer.verifier. Forse l'EjbDeployer.verifer ha un accesso ad javax.jms.Message in un altro ClassLoader come MyMDB. Come risultato, sia javax.jms.Message non sono uguali tra loro, anche se sono lo stesso byte-codice ed esiste letteralmente. L'EjbVerifier avvertirà su onMessage mancante, perché javax.jms.Message su ClassLoader A non è uguale a javax.jms.Message su ClassLoader B.

Questo può accadere quando le librerie con javax.jms.Message viene copiato su posti sbagliati sul JBoss AS. Quindi credo che - a distanza - che ci sia alcuni vasi contenenti javax.jms.Message in posti sbagliati sul JBoss o EAR. Per esempio alcuni jbossallclient.jar sbagliato nel EAR.

Altri suggerimenti

Assicurati che il tuo EAR non contenga le proprie copie delle classi javax.ejb (o tutte le classi javax a tutti, è per questo). JBoss 4 e 6 hanno piuttosto semantica diversa classloading, e ciò che funziona su un unico potrebbero non funzionare dall'altra. Per esempio, se lib del vostro orecchio conteneva le proprie copie di Message o MessageListener, allora può non funzionano più.

L'ho provato su "JBossAS [6.0.0.20100911-M5 "Neo"]" e 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
    }
}

e questa impostazione opere. Avete le stesse importazioni per il bean (forse c'era un importazione automatica sbagliato andata ???)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top