Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 1.4, 2.2
    • Fix Version/s: 3.0
    • Component/s: Telnet
    • Labels:
      None
    • Environment:

      Windows XP, Java JRE 1.6

      Description

      Hello

      I am using Telnet library of common.net. And I got an exception

      in TelnetInputStream once in a while.

      The exception message was as following.

      ------------------------------------------------------------------------
      --------------------------------------------

      Exception in thread "Thread-9399" java.lang.IllegalStateException: Queue
      is full! Cannot process another character.

      at
      org.apache.commons.net.telnet.TelnetInputStream.__processChar(TelnetInpu
      tStream.java:306)

      at
      org.apache.commons.net.telnet.TelnetInputStream.run(TelnetInputStream.ja
      va:596)

      at java.lang.Thread.run(Thread.java:619)

      ------------------------------------------------------------------------
      --------------------------------------------

      At first, I think it is possible that I didn't call read() in time to
      read the data in TelnetInputStream so that the buffer

      of TelnetInputStream overflowed. But then I wrote a simple program to
      test it and I found that it is not the cause.

      Then I studied the source of TelnetInputStream. The segment of function
      __processChar is as following.

      280
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#280> private void __processChar(int ch) throws
      InterruptedException
      281
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#281> {
      282
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#282> // Critical section because we're
      altering __bytesAvailable,
      283
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#283> // __queueTail, and the contents of
      _queue.
      284
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#284> synchronized (__queue)
      285
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#285> {
      286
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#286> while (__bytesAvailable >=
      __queue.length - 1)
      287
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#287> {
      288
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#288> // The queue is full. We need to
      wait before adding any more data to it. Hopefully the stream owner
      289
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#289> // will consume some data soon!
      290
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#290> if(__threaded)
      291
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#291> {
      292
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#292> __queue.notify();
      293
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#293> try
      294
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#294>

      { 295 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#295> __queue.wait(); 296 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#296> }

      297
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#297> catch (InterruptedException
      e)
      298
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#298>

      { 299 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#299> throw e; 300 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#300> }

      301
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#301> }
      302
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#302> else
      303
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#303>

      { 304 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#304> // We've been asked to add another character to the queue, but it is already full and there's 305 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#305> // no other thread to drain it. This should not have happened! 306 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#306> throw new IllegalStateException("Queue is full! Cannot process another character."); 307 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#307> }

      308
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#308> }
      309
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#309>
      310
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#310> // Need to do this in case we're not
      full, but block on a read
      311
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#311> if (__readIsWaiting && __threaded)
      312
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#312>

      { 313 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#313> __queue.notify(); 314 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#314> }

      315
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#315>
      316
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#316> __queue[__queueTail] = ch;
      317
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#317> ++__bytesAvailable;
      318
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#318>
      319
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#319> if (++__queueTail >= __queue.length)
      320
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#320> __queueTail = 0;
      321
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#321> }
      322
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#322> }

      In line 306 the exception IllegalStateException is thrown. In this
      condition, the variable __threaded should be false.

      But I didn't call TelnetClient.setReaderThread
      <http://commons.apache.org/net/api/org/apache/commons/net/telnet/TelnetC
      lient.html#setReaderThread%28boolean%29> to set it to false.

      The __threaded is set to true in _start() of TelnetInputStream

      84
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#84> void _start()
      85
      <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet
      InputStream.html#85>

      { 86 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#86> if(__thread == null) 87 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#87> return; 88 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#88> 89 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#89> int priority; 90 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#90> __isClosed = false; 91 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#91> // TODO remove this 92 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#92> // Need to set a higher priority in case JVM does not use pre-emptive 93 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#93> // threads. This should prevent scheduler induced deadlock (rather than 94 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#94> // deadlock caused by a bug in this code). 95 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#95> priority = Thread.currentThread().getPriority() + 1; 96 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#96> if (priority > Thread.MAX_PRIORITY) 97 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#97> priority = Thread.MAX_PRIORITY; 98 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#98> __thread.setPriority(priority); 99 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#99> __thread.setDaemon(true); 100 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#100> __thread.start(); 101 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#101> __threaded = true; 102 <http://commons.apache.org/net/xref/org/apache/commons/net/telnet/Telnet InputStream.html#102> }

      I guess that is there a possibility that the thread in __thread.start()
      is started so fast that when __processChar() is called, the __threaded
      has not been set to true.
      So the exception IllegalStateException is thrown.
      I think line 101 should be moved up of line 100.

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              krishiyer Krishnan Sivaramakrishna Iyer
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: