distribuzione jBoss di violazione spec bean message-driven
-
10-10-2019 - |
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 ??
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 ???)