Uploaded image for project: 'MINA'
  1. MINA
  2. DIRMINA-574

ClassCastException when a message is written on a closed session.

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Blocker
    • Resolution: Won't Fix
    • Affects Version/s: 1.0.10, 1.1.7, 2.0.0-M1
    • Fix Version/s: 2.0.8
    • Component/s: Core
    • Labels:
      None

      Description

      Steps to reproduce:
      1) Connection is closed at the socket level.
      2) A user writes a message.
      3) the message is encoded by a ProtocolCodecFilter.
      4) MINA notices the closed socket and fires a sessionClosed event.
      5) After the sessionClosed event is fired, IoFilterChain.clear() is called.
      6) MINA tries to write the user write request, but the session is closed already - all write requests are discarded.
      7) Before MINA discards all write requests, MINA checks if the first item in the queue is an empty buffer, which means a special separator which is handled by ProtocolCodecFilter.
      8) If there's an empty buffer in the head of the queue, MINA fires a messageSent event with the empty buffer in the hope that ProtocolCodecFilter will catch it.
      9) However, the filter chain is empty and therefore IoHandler implementation gets ClassCastException.

      A possible workaround is just to ignore the exception, but we need to provide a correct fix for this issue.

      The following is the stack trace that explains this scenario:

      25151 [SocketAcceptorIoProcessor-0.4] WARN ServerPortSessionHandler -
      > [/127.0.0.1:57120 <http://127.0.0.1:57120>]
      > java.lang.ClassCastException:
      > org.apache.mina.filter.codec.ProtocolCodecFilter$MessageByteBuffer
      > incompatible with com.daishin.eai.adapter.socket.message.Por
      > tMessage
      > at
      > com.daishin.eai.adapter.socket.handler.ServerPortSessionHandler.messageSent(ServerPortSessionHandler.java:80)
      > at
      > org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.messageSent(AbstractIoFilterChain.java:579)
      > at
      > org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageSent(AbstractIoFilterChain.java:320)
      > at
      > org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:53)
      > at
      > org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageSent(AbstractIoFilterChain.java:653)
      > at
      > org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageSent(AbstractIoFilterChain.java:504)
      > at
      > org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageSent(AbstractIoFilterChain.java:320)
      > at
      > org.apache.mina.common.support.AbstractIoFilterChain.fireMessageSent(AbstractIoFilterChain.java:314)
      > at
      > org.apache.mina.transport.socket.nio.SocketIoProcessor.releaseWriteBuffers(SocketIoProcessor.java:359)
      > at
      > org.apache.mina.transport.socket.nio.SocketIoProcessor.doFlush(SocketIoProcessor.java:314)
      > at
      > org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:45)
      > at
      > org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:488)
      > at
      > org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
      > at
      > java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:665)
      > at
      > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:690)
      > at java.lang.Thread.run(Thread.java:810)

        Activity

        Hide
        elecharny Emmanuel Lecharny added a comment -

        The Worker does not check if the Selected key is valid or not. In this case, if the connection has been closed, the SelectedKey will be invalid, thus should not be processed. As it's not checked, it is processed, leading to the problem.

        We should always check if the selected key is valid before doing any kind of processing, but that mean a deep refactoring of the selectedHandles() method.

        Show
        elecharny Emmanuel Lecharny added a comment - The Worker does not check if the Selected key is valid or not. In this case, if the connection has been closed, the SelectedKey will be invalid, thus should not be processed. As it's not checked, it is processed, leading to the problem. We should always check if the selected key is valid before doing any kind of processing, but that mean a deep refactoring of the selectedHandles() method.
        Hide
        elecharny Emmanuel Lecharny added a comment -

        raised to blocker, as the underlaying logic used to handle selected keys is flawed.

        Show
        elecharny Emmanuel Lecharny added a comment - raised to blocker, as the underlaying logic used to handle selected keys is flawed.
        Hide
        elecharny Emmanuel Lecharny added a comment -

        The best way to fix this issue is to avoid emitting this totally useless MessageSent event. I don't know why it has been created, but in any case, it will be a relief to get rid of it, as it generates problems and does not help at all...

        Show
        elecharny Emmanuel Lecharny added a comment - The best way to fix this issue is to avoid emitting this totally useless MessageSent event. I don't know why it has been created, but in any case, it will be a relief to get rid of it, as it generates problems and does not help at all...
        Hide
        elecharny Emmanuel Lecharny added a comment -

        Will be fixed when the MessageSent message will be removed, something that can't be done for 2.0

        Show
        elecharny Emmanuel Lecharny added a comment - Will be fixed when the MessageSent message will be removed, something that can't be done for 2.0
        Hide
        elecharny Emmanuel Lecharny added a comment -

        The logic is broken, but does not harm. It will be fixed in 3.0

        Show
        elecharny Emmanuel Lecharny added a comment - The logic is broken, but does not harm. It will be fixed in 3.0

          People

          • Assignee:
            elecharny Emmanuel Lecharny
            Reporter:
            trustin Trustin Lee
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development