Details
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>
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>
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>
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>
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>
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.