You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by manan <ma...@gcrj.com> on 2009/12/04 01:40:06 UTC

The exception of IllegalStateException in TelnetInputStream

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.