EJB3 - Вставить MDB в другой MDB? - PullRequest
1 голос
/ 23 ноября 2011

Поскольку бин, управляемый сообщениями, является типом EJB, я ожидал, что смогу внедрить одно в другое, но у меня есть проблемы.Мне нужно MDB и мне нужно внедрить одно в другое примерно так:

@MessageDriven(mappedName = "jms/QueueOne")
public class MessageBeanOne
{
    @EJB
    private EntityService service;

    @EJB
    private MessageBeanTwo mdbTwo;

    public void onMessage(Message message)
    {
        log.info("Received message from jms/QueueOne: " + message);
        String entityId= null;

        try
        {
            if (message instanceof TextMessage)
            {
                entityId = ((TextMessage) message).getText();
            }
            else
            {
                // error handling
            }
        }
        catch (Exception ex)
        {
           // error handling
        }

        Entity myEntity = service.getEntity(entityId);
        mdbTwo.process(myEntity);
    }
}


@MessageDriven(mappedName = "jms/TopicOne")
public class MessageBeanTwo
{
    @EJB
    private EntityService service;

    private boolean goodToProcess = true;

    public void process(Entity entity)
    {
        while(goodToProcess)
        {
            // process entity using injected service object
        }
    }

    public void onMessage(Message message)
    {
        log.info("Received message from jms/TopicOne: " + message);
        String status = null;

        try
        {
            if (message instanceof TextMessage)
            {
                status = ((TextMessage) message).getText();
            }
            else
            {
                // error handling
            }
        }
        catch (Exception ex)
        {
           // error handling
        }

        if (status.equals("cancel")
        {
            goodToProcess = false;
        }
    }
}

Они развернуты как Glassfish 3.1.1.и я получаю это сообщение об ошибке в моем server.log:

[#|2011-11-23T10:55:35.546-0700|SEVERE|glassfish3.1.1|javax.enterprise.system.container.ejb.mdb.com.sun.ejb.containers|_ThreadID=19;_ThreadName=Thread-2;|MDB00050: Message-driven bean [MyApp-ear-1.0:MessageBeanOne]: Exception in creating message-driven ejb : [com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Remote ejb-ref name=my.package.MessageBeanOne/messageBeanTwo,Remote 3.x interface =my.package.MessageBeanTwo,ejb-link=null,lookup=,mappedName=,jndi-name=my.package.MessageBeanTwo,refType=Session into class my.package.MessageBeanOne: Lookup failed for 'java:comp/env/my.package.MessageBeanOne/messageBeanTwo' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}]|#]
[#|2011-11-23T10:55:35.547-0700|SEVERE|glassfish3.1.1|javax.enterprise.system.container.ejb.mdb.com.sun.ejb.containers|_ThreadID=19;_ThreadName=Thread-2;|com.sun.enterprise.container.common.spi.util.InjectionException com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Remote ejb-ref name=my.package.MessageBeanOne/messageBeanTwo,Remote 3.x interface =my.package.MessageBeanTwo,ejb-link=null,lookup=,mappedName=,jndi-name=my.package.MessageBeanTwo,refType=Session into class my.package.MessageBeanOne: Lookup failed for 'java:comp/env/my.package.MessageBeanOne/messageBeanTwo' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}
        at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:703)
        at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:470)
        at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:171)
        at com.sun.ejb.containers.BaseContainer.injectEjbInstance(BaseContainer.java:1691)
        at com.sun.ejb.containers.MessageBeanContainer.createMessageDrivenEJB(MessageBeanContainer.java:706)
        at com.sun.ejb.containers.MessageBeanContainer.access$100(MessageBeanContainer.java:101)
        at com.sun.ejb.containers.MessageBeanContainer$MessageBeanContextFactory.create(MessageBeanContainer.java:483)
        at com.sun.ejb.containers.util.pool.NonBlockingPool.getObject(NonBlockingPool.java:247)
        at com.sun.ejb.containers.MessageBeanContainer._getContext(MessageBeanContainer.java:547)
        at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2528)
        at com.sun.ejb.containers.MessageBeanContainer.beforeMessageDelivery(MessageBeanContainer.java:989)
        at com.sun.ejb.containers.MessageBeanListenerImpl.beforeMessageDelivery(MessageBeanListenerImpl.java:77)
        at com.sun.enterprise.connectors.inbound.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:139)
        at $Proxy337.beforeDelivery(Unknown Source)
        at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java:247)
        at com.sun.enterprise.connectors.work.OneWork.doWork(OneWork.java:114)
        at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:497)
        at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:540)
Caused by: javax.naming.NamingException: Lookup failed for 'java:comp/env/my.package.MessageBeanOne/messageBeanTwo' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=my.package.MessageBeanOne/messageBeanTwo,Remote 3.x interface =my.package.MessageBeanTwo,ejb-link=null,lookup=,mappedName=,jndi-name=my.package.MessageBeanTwo,refType=Session' .  Actual (possibly internal) Remote JNDI name used for lookup is 'my.package.MessageBeanTwo#my.package.MessageBeanTwo' [Root exception is javax.naming.NamingException: Lookup failed for 'my.package.MessageBeanTwo#my.package.MessageBeanTwo' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: my.package.MessageBeanTwo#my.package.MessageBeanTwo not found]]]
        at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518)
        at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
        at javax.naming.InitialContext.lookup(InitialContext.java:392)
        at javax.naming.InitialContext.lookup(InitialContext.java:392)
        at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:599)
        ... 17 more
Caused by: javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=my.package.MessageBeanOne/messageBeanTwo,Remote 3.x interface =my.package.MessageBeanTwo,ejb-link=null,lookup=,mappedName=,jndi-name=my.package.MessageBeanTwo,refType=Session' .  Actual (possibly internal) Remote JNDI name used for lookup is 'my.package.MessageBeanTwo#my.package.MessageBeanTwo' [Root exception is javax.naming.NamingException: Lookup failed for 'my.package.MessageBeanTwo#my.package.MessageBeanTwo' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: my.package.MessageBeanTwo#my.package.MessageBeanTwo not found]]
        at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:178)
        at com.sun.enterprise.container.common.impl.ComponentEnvManagerImpl$EjbReferenceProxy.create(ComponentEnvManagerImpl.java:1106)
        at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:776)
        at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:744)
        at com.sun.enterprise.naming.impl.JavaURLContext.lookup(JavaURLContext.java:172)
        at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:498)
        ... 21 more
Caused by: javax.naming.NamingException: Lookup failed for 'my.package.MessageBeanTwo#my.package.MessageBeanTwo' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: my.package.MessageBeanTwo#my.package.MessageBeanTwo not found]
        at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518)
        at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
        at javax.naming.InitialContext.lookup(InitialContext.java:392)
        at javax.naming.InitialContext.lookup(InitialContext.java:392)
        at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:173)
        ... 26 more
Caused by: javax.naming.NameNotFoundException: my.package.MessageBeanTwo#my.package.MessageBeanTwo not found
        at com.sun.enterprise.naming.impl.TransientContext.doLookup(TransientContext.java:248)
        at com.sun.enterprise.naming.impl.TransientContext.lookup(TransientContext.java:215)
        at com.sun.enterprise.naming.impl.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:77)
        at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:119)
        at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:505)
        ... 30 more
|#]

[#|2011-11-23T10:55:35.548-0700|WARNING|glassfish3.1.1|javax.resourceadapter.mqjmsra.inbound.message|_ThreadID=19;_ThreadName=Thread-2;|MQJMSRA_MR2001: run:Caught Exception from onMessage():Redelivering:
javax.ejb.EJBException: ESwimMessageBeanTwo-ear-1.0:MessageBeanOne: message-driven bean invocation closed by container
        at com.sun.ejb.containers.MessageBeanContainer.deliverMessage(MessageBeanContainer.java:1163)
        at com.sun.ejb.containers.MessageBeanListenerImpl.deliverMessage(MessageBeanListenerImpl.java:81)
        at com.sun.enterprise.connectors.inbound.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:171)
        at $Proxy337.onMessage(Unknown Source)
        at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java:260)
        at com.sun.enterprise.connectors.work.OneWork.doWork(OneWork.java:114)
        at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:497)
        at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:540)
|#]

При попытке поиска, если это действительно возможно, я сталкивался с множеством ссылок на внедрение MDB в бины Session, но никогдаMDB в другой MDB.Может быть, это не выполнимо?

1 Ответ

1 голос
/ 23 ноября 2011

Возможно, это не имеет прямого отношения к вопросу, но я бы извлек метод process() в его собственный класс, который могут быть изменены обоими MDB.Таким образом, MDB несут исключительную ответственность за обработку входящих сообщений, а третий новый класс выполняет «обработку объекта».Тогда этот класс может быть другим EJB-компонентом, который вы вставляете в оба MDB.

По моему мнению, MDB, как правило, должны выделяться только для обработки принимаемых сообщений.

EDIT

Посмотревво второй раз я бы посоветовал вам подумать об этом дважды.Ваши MDB имеют состояние, и это может привести к неожиданным результатам, учитывая, что контейнер создает пул экземпляров.Вы можете оказаться в ситуации, когда экземпляр MessageBeanTwo объединен с goodToProcess = false.Если этот экземпляр взят из пула и введен в методе MessageBeanOne и process(), вы можете получить неверный результат.

Все это предполагает, что вы можете внедрить MDB в другой файл, который яникогда не делал и не слышал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...