weblogic JMS 消息 自动重连

问题遇到的现象和发生背景

weblogic重启后,TopicSubscriber不会收到新发送过来的消息,要重新启动Java程序,它才可以接收到消息。

用代码块功能插入代码,请勿粘贴截图
package com;

import com.pojo.User;
import weblogic.jms.common.TextMessageImpl;

import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Hashtable;

/**
 * 功能:
 * 作者:whk
 * 时间:2022/11/16 15:03
 * 版本:1.0
 **/
public class Test2 {
    Test2() {
        initContext();
        getSession();
        getTopicSubscriber();
        getTopicPublisher();
    }

    // Defines the JNDI context factory.
    public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";

    // Defines the JNDI provider url.
    public final static String PROVIDER_URL = "t3://localhost:7001";

    // Defines the JMS connection factory for the topic.
    public final static String CONNECTION_FACTORY_JNDI_NAME = "jms.ConnectionFactory-0whk";
    public final static String CONNECTION_FACTORY_JNDI_NAME2 = "javax.jms.TopicConnectionFactory";

    // Defines the topic, use the topic JNDI name
    public final static String TOPIC_JNDI_NAME = "jms/WHKTopic";

    public void initContext() {
        Hashtable table = new Hashtable();
        table.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
        table.put(Context.PROVIDER_URL, PROVIDER_URL);
        try {
            ctx = new InitialContext(table);
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    InitialContext ctx;
    Topic topic;
    TopicSession topicSession;
    TopicConnection topicConnection;
    TopicPublisher publisher;
    TopicSubscriber subscriber;

    private void getSession() {
        try {
            TopicConnectionFactory tconFactory = (TopicConnectionFactory) ctx.lookup(CONNECTION_FACTORY_JNDI_NAME);
            topicConnection = tconFactory.createTopicConnection();
            topic = (Topic) ctx.lookup(TOPIC_JNDI_NAME);
            topicSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void getTopicPublisher() {
        try {
            publisher = topicSession.createPublisher(topic);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void getTopicSubscriber() {
        try {
            subscriber = topicSession.createSubscriber(topic);
            subscriber.setMessageListener(new MessageListener() {
                @Override
                public void onMessage(Message message) {
                    try {
                        String msgStr = "";
                        int age = 0;

                        if (message instanceof TextMessage) {
                            msgStr = ((TextMessage) message).getText();
                        } else if (message instanceof StreamMessage) {
                            msgStr = ((StreamMessage) message).readString();
                            age = ((StreamMessage) message).readInt();
                        } else if (message instanceof BytesMessage) {
                            byte[] block = new byte[1024];
                            ((BytesMessage) message).readBytes(block);
                            msgStr = String.valueOf(block);
                        } else if (message instanceof MapMessage) {
                            msgStr = ((MapMessage) message).getString("name");
                        } else if (message instanceof ObjectMessage) {
                            User user = (User) ((ObjectMessage) message).getObject();
                            msgStr = user.getName();
                            age = user.getAge();
                        }

                        System.out.println("Message subscribed: " + msgStr + ", " + age);
                    } catch (JMSException e) {
                        throw new RuntimeException("error happens", e);
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void close() {
        try {
            if (publisher != null)
                publisher.close();
            if (subscriber != null)
                subscriber.close();
            if (topicSession != null)
                topicSession.close();
            if (topicConnection != null)
                topicConnection.close();
            if (ctx!=null)
                ctx.close();
        } catch (JMSException | NamingException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        try {
            Test2 test2 = new Test2();
            TopicPublisher topicPublisher = test2.publisher;
            test2.topicConnection.start();

            boolean flag = true;
            try {
                while (flag) {

                    topicPublisher.publish(new TextMessageImpl("publish message"));
                    Thread.sleep(5000);
                }
            } catch (JMSException | InterruptedException e) {
                System.out.println("第一个while断开");
            }
            test2.close();
            while (flag) {
                try {
                    Test2 test = new Test2();
                    Thread.sleep(5000);
                    test.publisher.publish(new TextMessageImpl("publish message"));
                    flag = false;
                } catch (NullPointerException e) {
                    System.out.println("空指针,即连接失败创建失败");
                }catch (JMSException | InterruptedException e) {
                    System.out.println("测试发送循环");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
运行结果及报错内容

对象被关闭

Message subscribed: publish message, 0
Message subscribed: publish message, 0
第一个while断开
十一月 18, 2022 2:18:59 下午 com.sun.corba.se.impl.orb.ORBImpl checkShutdownState
警告: "IOP01600004: (BAD_INV_ORDER) ORB has shutdown"
org.omg.CORBA.BAD_INV_ORDER:   vmcid: OMG  minor code: 4  completed: No
    at com.sun.corba.se.impl.logging.OMGSystemException.badOperationAfterShutdown(OMGSystemException.java:224)
    at com.sun.corba.se.impl.logging.OMGSystemException.badOperationAfterShutdown(OMGSystemException.java:246)
    at com.sun.corba.se.impl.orb.ORBImpl.checkShutdownState(ORBImpl.java:1341)
    at com.sun.corba.se.impl.orb.ORBImpl.getThreadPoolManager(ORBImpl.java:2082)
    at com.sun.corba.se.impl.transport.SelectorImpl.createListenerThread(SelectorImpl.java:512)
    at com.sun.corba.se.impl.transport.SelectorImpl.registerForEvent(SelectorImpl.java:167)
    at com.sun.corba.se.impl.transport.SocketOrChannelAcceptorImpl.accept(SocketOrChannelAcceptorImpl.java:285)
    at com.sun.corba.se.impl.transport.ListenerThreadImpl.doWork(ListenerThreadImpl.java:97)
    at com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:490)
    at com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:519)

javax.naming.NamingException: Couldn't connect to the specified host [Root exception is org.omg.CORBA.COMM_FAILURE:   vmcid: SUN  minor code: 203  completed: No]
    at weblogic.corba.j2ee.naming.Utils.wrapNamingException(Utils.java:83)
    at weblogic.corba.j2ee.naming.ORBHelper.getORBReferenceWithRetry(ORBHelper.java:656)
    at weblogic.corba.j2ee.naming.ORBHelper.getORBReference(ORBHelper.java:594)
    at weblogic.corba.j2ee.naming.InitialContextFactoryImpl.getInitialContext(InitialContextFactoryImpl.java:85)
    at weblogic.corba.j2ee.naming.InitialContextFactoryImpl.getInitialContext(InitialContextFactoryImpl.java:31)
    at weblogic.jndi.WLInitialContextFactory.getInitialContext(WLInitialContextFactory.java:46)
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
    at javax.naming.InitialContext.init(InitialContext.java:244)
    at javax.naming.InitialContext.(InitialContext.java:216)
    at com.Test2.initContext(Test2.java:44)
    at com.Test2.(Test2.java:20)
    at com.Test2.main(Test2.java:151)
Caused by: org.omg.CORBA.COMM_FAILURE:   vmcid: SUN  minor code: 203  completed: No
    at com.sun.corba.se.impl.logging.ORBUtilSystemException.writeErrorSend(ORBUtilSystemException.java:2259)
    at com.sun.corba.se.impl.logging.ORBUtilSystemException.writeErrorSend(ORBUtilSystemException.java:2281)
    at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.writeLock(SocketOrChannelConnectionImpl.java:981)
    at com.sun.corba.se.impl.encoding.BufferManagerWriteGrow.sendMessage(BufferManagerWriteGrow.java:86)
    at com.sun.corba.se.impl.encoding.CDROutputObject.finishSendingMessage(CDROutputObject.java:162)
    at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.finishSendingRequest(CorbaMessageMediatorImpl.java:265)
    at com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.marshalingComplete1(CorbaClientRequestDispatcherImpl.java:389)
    at com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.marshalingComplete(CorbaClientRequestDispatcherImpl.java:371)
    at com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.invoke(CorbaClientDelegateImpl.java:148)
    at com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.non_existent(CorbaClientDelegateImpl.java:250)
    at org.omg.CORBA.portable.ObjectImpl._non_existent(ObjectImpl.java:155)
    at weblogic.corba.j2ee.naming.ORBHelper.getORBReferenceWithRetry(ORBHelper.java:633)
    ... 11 more
java.lang.NullPointerException
    at com.Test2.getSession(Test2.java:59)
    at com.Test2.(Test2.java:21)
    at com.Test2.main(Test2.java:151)
java.lang.NullPointerException
    at com.Test2.getTopicSubscriber(Test2.java:78)
    at com.Test2.(Test2.java:22)
    at com.Test2.main(Test2.java:151)
java.lang.NullPointerException
    at com.Test2.getTopicPublisher(Test2.java:70)
    at com.Test2.(Test2.java:23)
    at com.Test2.main(Test2.java:151)
空指针,即连接失败创建失败
十一月 18, 2022 2:19:08 下午 com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolManagerImpl close
警告: "IOP00710328: (INTERNAL) ThreadGroup java.lang.ThreadGroup[name=ORB ThreadGroup 4,maxpri=10] has 1 active threads: destroy may cause exception"
org.omg.CORBA.INTERNAL:   vmcid: SUN  minor code: 328  completed: No
    at com.sun.corba.se.impl.logging.ORBUtilSystemException.threadGroupHasActiveThreadsInClose(ORBUtilSystemException.java:6599)
    at com.sun.corba.se.impl.logging.ORBUtilSystemException.threadGroupHasActiveThreadsInClose(ORBUtilSystemException.java:6623)
    at com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolManagerImpl.close(ThreadPoolManagerImpl.java:129)
    at com.sun.corba.se.impl.orb.ORBImpl.destroy(ORBImpl.java:1411)
    at weblogic.corba.j2ee.naming.ORBHelper.destroyORB(ORBHelper.java:804)
    at weblogic.corba.j2ee.naming.ORBHelper.getORBReferenceWithRetry(ORBHelper.java:648)
    at weblogic.corba.j2ee.naming.ORBHelper.getORBReference(ORBHelper.java:594)
    at weblogic.corba.j2ee.naming.InitialContextFactoryImpl.getInitialContext(InitialContextFactoryImpl.java:85)
    at weblogic.corba.j2ee.naming.InitialContextFactoryImpl.getInitialContext(InitialContextFactoryImpl.java:31)
    at weblogic.jndi.WLInitialContextFactory.getInitialContext(WLInitialContextFactory.java:46)
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
    at javax.naming.InitialContext.init(InitialContext.java:244)
    at javax.naming.InitialContext.(InitialContext.java:216)
    at com.Test2.initContext(Test2.java:44)
    at com.Test2.(Test2.java:20)
    at com.Test2.main(Test2.java:151)

十一月 18, 2022 2:19:08 下午 com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolManagerImpl close
警告: "IOP00710330: (INTERNAL) ThreadGroup java.lang.ThreadGroup[name=ORB ThreadGroup 4,maxpri=10] could not be destroyed"
org.omg.CORBA.INTERNAL:   vmcid: SUN  minor code: 330  completed: No
    at com.sun.corba.se.impl.logging.ORBUtilSystemException.threadGroupDestroyFailed(ORBUtilSystemException.java:6659)
    at com.sun.corba.se.impl.logging.ORBUtilSystemException.threadGroupDestroyFailed(ORBUtilSystemException.java:6678)
    at com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolManagerImpl.close(ThreadPoolManagerImpl.java:137)
    at com.sun.corba.se.impl.orb.ORBImpl.destroy(ORBImpl.java:1411)
    at weblogic.corba.j2ee.naming.ORBHelper.destroyORB(ORBHelper.java:804)
    at weblogic.corba.j2ee.naming.ORBHelper.getORBReferenceWithRetry(ORBHelper.java:648)
    at weblogic.corba.j2ee.naming.ORBHelper.getORBReference(ORBHelper.java:594)
    at weblogic.corba.j2ee.naming.InitialContextFactoryImpl.getInitialContext(InitialContextFactoryImpl.java:85)
    at weblogic.corba.j2ee.naming.InitialContextFactoryImpl.getInitialContext(InitialContextFactoryImpl.java:31)
    at weblogic.jndi.WLInitialContextFactory.getInitialContext(WLInitialContextFactory.java:46)
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
    at javax.naming.InitialContext.init(InitialContext.java:244)
    at javax.naming.InitialContext.(InitialContext.java:216)
    at com.Test2.initContext(Test2.java:44)
    at com.Test2.(Test2.java:20)
    at com.Test2.main(Test2.java:151)
Caused by: java.lang.IllegalThreadStateException
    at java.lang.ThreadGroup.destroy(ThreadGroup.java:778)
    at com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolManagerImpl.close(ThreadPoolManagerImpl.java:134)
    ... 14 more

javax.naming.NamingException: Couldn't connect to the specified host : write not supported [Root exception is org.omg.CORBA.COMM_FAILURE:   vmcid: SUN  minor code: 203 completed: Maybe]
    at weblogic.corba.j2ee.naming.Utils.wrapNamingException(Utils.java:83)
    at weblogic.corba.j2ee.naming.ORBHelper.getORBReferenceWithRetry(ORBHelper.java:656)
    at weblogic.corba.j2ee.naming.ORBHelper.getORBReference(ORBHelper.java:594)
    at weblogic.corba.j2ee.naming.InitialContextFactoryImpl.getInitialContext(InitialContextFactoryImpl.java:85)
    at weblogic.corba.j2ee.naming.InitialContextFactoryImpl.getInitialContext(InitialContextFactoryImpl.java:31)
    at weblogic.jndi.WLInitialContextFactory.getInitialContext(WLInitialContextFactory.java:46)
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
    at javax.naming.InitialContext.init(InitialContext.java:244)
    at javax.naming.InitialContext.(InitialContext.java:216)
    at com.Test2.initContext(Test2.java:44)
    at com.Test2.(Test2.java:20)
    at com.Test2.main(Test2.java:151)
Caused by: org.omg.CORBA.COMM_FAILURE:   vmcid: SUN  minor code: 203 completed: Maybe
    at com.sun.corba.se.impl.logging.ORBUtilSystemException.writeErrorSend(ORBUtilSystemException.java:2259)
    at com.sun.corba.se.impl.logging.ORBUtilSystemException.writeErrorSend(ORBUtilSystemException.java:2277)
    at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.sendWithoutLock(SocketOrChannelConnectionImpl.java:1090)
    at com.sun.corba.se.impl.encoding.BufferManagerWriteGrow.sendMessage(BufferManagerWriteGrow.java:90)
    at com.sun.corba.se.impl.encoding.CDROutputObject.finishSendingMessage(CDROutputObject.java:162)
    at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.finishSendingRequest(CorbaMessageMediatorImpl.java:265)
    at com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.marshalingComplete1(CorbaClientRequestDispatcherImpl.java:389)
    at com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.marshalingComplete(CorbaClientRequestDispatcherImpl.java:371)
    at com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.invoke(CorbaClientDelegateImpl.java:148)
    at com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.non_existent(CorbaClientDelegateImpl.java:250)
    at org.omg.CORBA.portable.ObjectImpl._non_existent(ObjectImpl.java:155)
    at weblogic.corba.j2ee.naming.ORBHelper.getORBReferenceWithRetry(ORBHelper.java:633)
    ... 11 more
Caused by: java.io.IOException: write not supported
    at weblogic.corba.client.cluster.DummySocket$2.write(DummySocket.java:35)
    at java.io.OutputStream.write(OutputStream.java:116)
    at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.write(SocketOrChannelConnectionImpl.java:745)
    at com.sun.corba.se.impl.encoding.CDROutputObject.writeTo(CDROutputObject.java:192)
    at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.sendWithoutLock(SocketOrChannelConnectionImpl.java:1040)
    ... 20 more
java.lang.NullPointerException
    at com.Test2.getSession(Test2.java:59)
    at com.Test2.(Test2.java:21)
    at com.Test2.main(Test2.java:151)
java.lang.NullPointerException
    at com.Test2.getTopicSubscriber(Test2.java:78)
    at com.Test2.(Test2.java:22)
    at com.Test2.main(Test2.java:151)
java.lang.NullPointerException
    at com.Test2.getTopicPublisher(Test2.java:70)
    at com.Test2.(Test2.java:23)
    at com.Test2.main(Test2.java:151)


我的解答思路和尝试过的方法

创建TopicPublisher定时发送消息,发送失败即证明weblogic离线,我们就要停止发送消息,关闭消费和生成对象,重新生成对象并发送消息(有一定的时间间隔),直至成功就继续保持成功状态,若再次离线,即重复步骤

我想要达到的结果

weblogic重启后,TopicSubscriber依然能接收到新的消息。

weblogic重启后,需要程序重新发起注册吧。