undertow websocket 热加载报错断开链接问题

我使用最新版本的undertow-core-2.2.2.Final,在没有任何更新class的情况下,websocket能正常运行。当加载了class,即热加载后,日志中报错:

Loading changes ......

2021-02-19 15:06:19
[WARN]-[Thread: HotSwapWatcher]-[com.jfinal.server.undertow.session.HotSwapSessionPersistenceManager.persistSessions()]: UT015009: Failed to persist session attribute io.undertow.websocket.current-connections with value [WebSocket13Channel peer /0:0:0:0:0:0:0:1:53188 local /0:0:0:0:0:0:0:1:7025[ No Receiver [] -- [] -- []]] for session K4RSVT3_lsLkeaHCDJy8XhSX2Xcm0L5zrO2cZTBf
java.io.NotSerializableException: io.undertow.websockets.core.protocol.version13.WebSocket13Channel
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at java.util.ArrayList.writeObject(ArrayList.java:766)
	at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1140)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at com.jfinal.server.undertow.session.HotSwapSessionPersistenceManager.persistSessions(HotSwapSessionPersistenceManager.java:50)
	at io.undertow.servlet.handlers.SessionRestoringHandler.stop(SessionRestoringHandler.java:108)
	at io.undertow.servlet.core.DeploymentManagerImpl$3.call(DeploymentManagerImpl.java:617)
	at io.undertow.servlet.core.DeploymentManagerImpl$3.call(DeploymentManagerImpl.java:612)
	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:42)
	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
	at io.undertow.servlet.core.DeploymentManagerImpl.stop(DeploymentManagerImpl.java:626)
	at com.jfinal.server.undertow.UndertowServer.doStop(UndertowServer.java:415)
	at com.jfinal.server.undertow.UndertowServer.restart(UndertowServer.java:433)
	at com.jfinal.server.undertow.hotswap.HotSwapWatcher.doRun(HotSwapWatcher.java:133)
	at com.jfinal.server.undertow.hotswap.HotSwapWatcher.run(HotSwapWatcher.java:91)

2021-02-19 15:06:19
[ERROR]-[Thread: XNIO-3 I/O-2]-[org.xnio.ChannelListeners.invokeChannelListener()]: XNIO001007: A channel event listener threw an exception
java.util.concurrent.RejectedExecutionException: XNIO007007: Thread is terminating
	at org.xnio.nio.WorkerThread.execute(WorkerThread.java:590)
	at io.undertow.websockets.jsr.UndertowSession$3.handleEvent(UndertowSession.java:396)
	at io.undertow.websockets.jsr.UndertowSession$3.handleEvent(UndertowSession.java:388)
	at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
	at io.undertow.server.protocol.framed.AbstractFramedChannel$FrameCloseListener.handleEvent(AbstractFramedChannel.java:1075)
	at io.undertow.server.protocol.framed.AbstractFramedChannel$FrameCloseListener.handleEvent(AbstractFramedChannel.java:990)
	at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
	at org.xnio.conduits.WriteReadyHandler$ChannelListenerHandler.terminated(WriteReadyHandler.java:70)
	at org.xnio.nio.NioSocketConduit.writeTerminated(NioSocketConduit.java:234)
	at org.xnio.nio.NioSocketConduit.terminateWrites(NioSocketConduit.java:223)
	at org.xnio.nio.NioSocketConduit.truncateWrites(NioSocketConduit.java:228)
	at io.undertow.conduits.IdleTimeoutConduit.truncateWrites(IdleTimeoutConduit.java:387)
	at org.xnio.conduits.ConduitStreamSinkChannel.close(ConduitStreamSinkChannel.java:186)
	at org.xnio.IoUtils.safeClose(IoUtils.java:134)
	at org.xnio.conduits.WriteReadyHandler$ChannelListenerHandler.forceTermination(WriteReadyHandler.java:57)
	at org.xnio.nio.NioSocketConduit.forceTermination(NioSocketConduit.java:107)
	at org.xnio.nio.WorkerThread.run(WorkerThread.java:494)


然后页面上就收不到消息了,需要刷新页面才可以。热加载或者重新启动服务器后,websokcet都是closed状态,都需要刷新页面。

请问下这个报错如何处理?

websocket能不能一直处于连接状态?或者断开后自动连接上?

评论区

JFinal

2021-02-19 16:39

为了维持热加载以后 session 中的数据可以使用,在热加载之前 session 中的数据会被持久化,而持久化需要被持久化的对象实现 Serializable 这个接口

检查一下你存放在 session 中的哪些数据是没有实现这个接口的,注意,不仅是直接对象,还要检查间接对象

此外,你给的信息中其实只有一个 error,其中第一个为 WARN,第二个为 ERROR,第二个是 RejectedExecutionException ,注意查明原因

北流家园网

2021-02-19 20:07

@JFinal io.undertow.websockets.core.protocol.version13.WebSocket13Channel 提示中是说这个没有实现 Serializable 这个接口,检查过实体类,原来是@SuppressWarnings("serial")的,我改为实现Serializable ,也一样报这个错,而且自动生成的Model就是@SuppressWarnings("serial")的。我百度了很多也没有找到解决方法。

zzutligang

2021-02-27 01:14

@北流家园网,我也遇到这样的问题。后台只要修改代码触发热加载,就会抛这个异常。但因为我前端页面实现了断开自动重连,所以,从使用上来说,避免了出错。只是后台抛这个异常,看起来别扭!