Jakarta ee EJB“;B";“从EJB看失败”;“A”;,如果在Glassfish中使用EJB在队列中实例化

Jakarta ee EJB“;B";“从EJB看失败”;“A”;,如果在Glassfish中使用EJB在队列中实例化,jakarta-ee,timer,glassfish,jms,ejb-3.0,Jakarta Ee,Timer,Glassfish,Jms,Ejb 3.0,Glassfish在以下情况下抛出异常(第二次EJB查找失败) 计时器服务->JMS队列侦听器->第一个EJB->第二个EJB 但是,如果删除了队列,则工作正常 计时器服务->第一个EJB->第二个EJB 注意:它们都位于同一空间的同一台服务器上 计时器服务每30秒运行一次,并向队列发送JMS消息 队列成功接收此消息,并调用实例化为@EJB FirstEjb的方法被成功调用,但是它尝试了另一个SecondEjb函数,该函数在其中被实例化为@EJB(该查找失败的原因之一) 定时器类 @Statel

Glassfish在以下情况下抛出异常(第二次
EJB
查找失败)

计时器服务->JMS队列侦听器->第一个EJB->第二个EJB

但是,如果删除了
队列
,则工作正常

计时器服务->第一个EJB->第二个EJB

注意:它们都位于同一空间的同一台服务器上

  • 计时器服务
    每30秒运行一次,并向队列发送
    JMS消息
  • 队列成功接收此消息,并调用实例化为
    @EJB
  • FirstEjb的方法被成功调用,但是它尝试了另一个SecondEjb函数,该函数在其中被实例化为
    @EJB
    (该查找失败的原因之一)
  • 定时器类

    @Stateless
    public class MyTimer {
        public static final  Logger logger = Logger.getLogger(MyTimer.class);
        public MyTimer() {
    
        }
    
        @Schedule(second="*/30", minute="*",hour="*", persistent=false)
        private void scheduledTimeout(final Timer t) {
            logger.warn("********************* MyTimer scheduledTimeout called ********************************");
    
            MyMessageSender sender = new MyMessageSender();
            sender.sendMessage(" /////////////// Here is my message for you ////////////// ");
        }
    } 
    
    public class MyMessageSender {
        public void sendMessage(String message) {
            Context jndiContext = null;
            Connection connection = null;
            Session session = null;
            MessageProducer producer = null;
            ConnectionFactory factory = null;
    
            try {
    
                jndiContext = new InitialContext();
    
                factory = (ConnectionFactory) jndiContext
                        .lookup(NewsUpdatesQueueListener.CONNECTION_FACTORY);
                connection = factory.createConnection();
                session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    
                if (session == null) {
                    System.out.println("session object is null");
                    return;
                }
                Queue queue = (Queue) jndiContext.lookup(NewsUpdatesQueueListener.CONNECTION_QUEUE_JNDI);
    
                if (queue == null) {
                    System.out.println("queue object for NewsUpdateQueue is null ");
                    return;
                }
                producer = session.createProducer(queue);
    
                ObjectMessage msg = session.createObjectMessage();
                msg.setStringProperty("text", message);
                session.createProducer(queue).send(msg);
    
            } catch (NamingException e) {
                e.printStackTrace();
            } catch (JMSException e) {
                e.printStackTrace();
            } finally {
    
                try {
                    if (connection != null) {
                        connection.close();
                    }
                    if (session != null) {
                        session.close();
                    }
    
                    if (producer != null) {
                        producer.close();
                    }
    
                } catch (JMSException e) {
                    e.printStackTrace();
                }
    
            }
        }
    } 
    
    消息发送者(助手类)

    队列侦听器

    @MessageDriven(
            activationConfig = { 
                    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
                    @ActivationConfigProperty( propertyName = "destination", propertyValue = NewsUpdatesQueueListener.CONNECTION_QUEUE_NAME)
                    }, 
            mappedName = NewsUpdatesQueueListener.CONNECTION_QUEUE_JNDI)
    
    public class NewsUpdatesQueueListener implements MessageListener {
        public static final  Logger logger = Logger.getLogger(NewsUpdatesQueueListener.class);
        public static final String CONNECTION_FACTORY = "jms/NewsConnectionFactory";
        public static final String CONNECTION_QUEUE_NAME = "NewsQueue";
        public static final String CONNECTION_QUEUE_JNDI = "jms/"+CONNECTION_QUEUE_NAME;
    
        @EJB 
        FirstEjbRemote first;
    
        public void onMessage(Message message) {
            if (message instanceof ObjectMessage) {
                ObjectMessage msg = (ObjectMessage) message;
                try {
                    logger.warn("Message recived in Queue listener: "+ msg.getStringProperty("text"));
                    if (first != null) 
                        first.hello();
                    else 
                        logger.warn("@EJB first is null");
    
                } catch (JMSException e) {
                    e.printStackTrace();
                }
                 catch (Exception e) {
                     e.printStackTrace();
                 }
            }
        }
    }
    
    第一个EJb

    @Stateless(name="FirstEjb", mappedName="ejb/FirstEjb")
    @Local(FirstEjbLocal.class)
    @Remote(FirstEjbRemote.class)
    public class FirstEjb implements FirstEjbRemote, FirstEjbLocal {
        public static final  Logger logger = Logger.getLogger(FirstEjb.class);
        @EJB
        SecondEjbRemote second;
    
    
        @Override
        public void hello() {
            logger.warn("********************* Hello function called in first EJB *********");
            if (second != null) 
                    second.sayHello();
        }
     }
    
    第二个EJB

    @Stateless(name="SecondEjb", mappedName = "ejb/SecondEjb")
    @Local(SecondEjbLocal.class)
    @Remote(SecondEjbRemote.class)
    public class SecondEjb implements SecondEjbRemote, SecondEjbLocal {
    
        @Override
        public void sayHello() {
            System.out.println("********************* Hello function called in second EJB *********");
    
        }
    }
    
    部署日志

        |INFO|glassfish3.1.2|EJB5181:Portable JNDI names for EJB SecondEjb: [java:global/AppleNew/SecondEjb!com.bbc.news.SecondEjbRemote, java:global/AppleNew/SecondEjb!com.bbc.news.SecondEjbLocal]|#]
        |INFO|glassfish3.1.2|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=37;_ThreadName=Thread-2;|EJB5182:Glassfish-specific (Non-portable) JNDI names for EJB SecondEjb: [ejb/SecondEjb, ejb/SecondEjb#com.bbc.news.SecondEjbRemote]|#]
        |INFO|glassfish3.1.2|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=37;_ThreadName=Thread-2;|EJB5181:Portable JNDI names for EJB MyTimer: [java:global/AppleNew/MyTimer!com.bbc.news.MyTimer, java:global/AppleNew/MyTimer]|#]
        |INFO|glassfish3.1.2|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=37;_ThreadName=Thread-2;|EJB5181:Portable JNDI names for EJB FirstEjb: [java:global/AppleNew/FirstEjb!com.bbc.news.FirstEjbLocal, java:global/AppleNew/FirstEjb!com.bbc.news.FirstEjbRemote]|#]
        |INFO|glassfish3.1.2|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=37;_ThreadName=Thread-2;|EJB5182:Glassfish-specific (Non-portable) JNDI names for EJB FirstEjb: [ejb/FirstEjb#com.bbc.news.FirstEjbRemote, ejb/FirstEjb]|#]
        |INFO|glassfish3.1.2|javax.enterprise.resource.jms.com.sun.enterprise.connectors.jms.system|_ThreadID=37;_ThreadName=Thread-2;|JMS013: end point determine destionation name, Res name: javax.jms.Queue, JNDI name: NewsUpdatesQueueListener descriptor name : {3}|#]
        |INFO|glassfish3.1.2|javax.enterprise.system.tools.admin.org.glassfish.deployment.admin|_ThreadID=37;_ThreadName=Thread-2;|AppleNew was successfully deployed in 332 milliseconds.|#]
    
    请注意若JMS队列被删除,计时器服务直接调用第一个ejb,而第一个ejb调用第二个ejb,则工作正常

    部分异常(从长异常的中间开始,如果需要,我将粘贴完整异常)

    2个工作正常的测试环境

    window 7
    GlassFish Server Open Source Edition 3.1.2 (build 23)
    java version "1.6.0_32"
    Java(TM) SE Runtime Environment (build 1.6.0_32-b05)
    Java HotSpot(TM) Client VM (build 20.7-b02, mixed mode, sharing)
    
    Ubuntu 12.04.2 LTS
    GlassFish Server Open Source Edition 3.0.1 (build 22)
    java version "1.6.0_30"
    OpenJDK Runtime Environment (IcedTea6 1.13.1) (6b30-1.13.1-1ubuntu2~0.12.04.3)
    OpenJDK Client VM (build 23.25-b01, mixed mode, sharing)
    
    测试虚拟机

    window 7
    GlassFish Server Open Source Edition 3.1.2 (build 23)
    java version "1.6.0_32"
    Java(TM) SE Runtime Environment (build 1.6.0_32-b05)
    Java HotSpot(TM) Client VM (build 20.7-b02, mixed mode, sharing)
    
    Ubuntu 12.04.2 LTS
    GlassFish Server Open Source Edition 3.0.1 (build 22)
    java version "1.6.0_30"
    OpenJDK Runtime Environment (IcedTea6 1.13.1) (6b30-1.13.1-1ubuntu2~0.12.04.3)
    OpenJDK Client VM (build 23.25-b01, mixed mode, sharing)
    

    兄弟,你试过用本地接口调用第二个EJB吗

    @EJB
    SecondEjbLocal second;
    @Override
    public void hello() {
        logger.warn("********************* Hello function called in first EJB *********");
        if (second != null) 
                second.sayHello();
    }
    

    兄弟,你试过用本地接口调用第二个EJB吗

    @EJB
    SecondEjbLocal second;
    @Override
    public void hello() {
        logger.warn("********************* Hello function called in first EJB *********");
        if (second != null) 
                second.sayHello();
    }
    

    看来你面临的问题与这个问题有关

    建议的解决方法是编辑
    domain.xml
    并添加到其中

    -Dorg.omg.CORBA.ORBSingletonClass=com.sun.corba.se.impl.orb.ORBSingleton
    
    jvmopts
    。默认情况下,
    org.omg.CORBA.ORBSingletonClass
    属性指向错误的类,而该类不存在


    如果它在其他环境下工作取决于您的陈述,我认为问题可能与Java版本有关,如原始错误报告中所述。这个问题似乎也与OpenJDK有关。

    您面临的问题似乎与这个问题有关

    建议的解决方法是编辑
    domain.xml
    并添加到其中

    -Dorg.omg.CORBA.ORBSingletonClass=com.sun.corba.se.impl.orb.ORBSingleton
    
    jvmopts
    。默认情况下,
    org.omg.CORBA.ORBSingletonClass
    属性指向错误的类,而该类不存在


    如果它在其他环境下工作取决于您的陈述,我认为问题可能与Java版本有关,如原始错误报告中所述。问题似乎也与OpenJDK有关。

    您使用的是哪个Java版本和哪个Glassfish版本?请查看更新的问题我添加了有关版本的详细信息。请查看此问题报告,也许这里描述的解决方法对您有用。您能否解释一下,指定JDK(在domain.xml jvmopts中)提供的默认ORB单例:-Dorg.omg.CORBA.ORBSingletonClass=com.sun.CORBA.se.impl.ORB.ORBSingleton为我“解决”了这个问题。您必须编辑domain.xml,找到一个名为jvmopts的元素,然后添加上面提到的字符串。这将设置所提到的系统属性,您使用的是哪个Java版本和哪个Glassfish版本?请查看更新的问题我添加了关于版本的详细信息。检查此问题报告,可能这里描述的解决方法对您有用。您能解释一下这一点吗?指定JDK提供的默认ORB单例(在domain.xml jvmopts中):-Dorg.omg.CORBA.ORBSingletonClass=com.sun.CORBA.se.impl.orb.ORBSingleton“已解决”这对我来说是个问题。你必须编辑domain.xml,找到一个名为jvmopts的元素,并在其中添加提到的字符串。这将设置提到的系统属性。这解决了我的问题,谢谢!只需提到在
    domain.xml
    中可能有多个
    部分需要编辑。我在两个位置添加了该字符串。这解决了我的问题lem,谢谢!只需提到在
    domain.xml
    中可能有多个
    部分需要编辑。我添加了两个地方。