jBoss 部署消息驱动 Bean 规范违规

发布于 2024-10-08 02:56:36 字数 2119 浏览 8 评论 0原文

我有一个 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,并且只重新添加了相关的 jar(也从新版本中)以消除 NoClassDefFound 错误。 但问题仍然存在。

编辑: 有什么指示吗?我应该看什么区域?我的项目,或者jboss配置,或者部署设置?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

白色秋天 2024-10-15 02:56:36

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 的类加载器。也许 EjbDeployer.verifer 可以作为 MyMDB 访问另一个 ClassLoader 中的 javax.jms.Message。因此,尽管 javax.jms.Message 是相同的字节码并且确实存在,但它们并不相等。 EjbVerifier 将警告缺少 onMessage,因为类加载器 A 上的 javax.jms.Message 不等于类加载器 B 上的 javax.jms.Message

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

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.

烧了回忆取暖 2024-10-15 02:56:36

确保您的 EAR 不包含自己的 javax.ejb 类副本(或任何 javax 类)。 JBoss 4 和 6 具有相当不同的类加载语义,在其中一种上有效的方法可能在另一种上不起作用。例如,如果您的 EAR 的 lib 包含它自己的 MessageMessageListener 副本,那么它可能不再工作。

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.

谷夏 2024-10-15 02:56:36

我在“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 是否有相同的导入(也许自动导入出错了???)

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文