[ 
https://issues.apache.org/jira/browse/THRIFT-5081?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Chris Miller updated THRIFT-5081:
---------------------------------
    Description: 
The following Java code runs successfully, but causes Thrift to log a warning 
inside TIOStreamTransport:

 
{code:java}
    TTransport transport = new TZlibTransport(new TSocket("localhost", 8000, 
1000));
    transport.close();{code}
The warning is as follows:

 

 
{code:java}
WARN org.apache.thrift.transport.TIOStreamTransport - Error closing output 
stream.
 java.net.SocketException: Socket closed
 at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:118) 
~[?:1.8.0_181]
 at java.net.SocketOutputStream.write(SocketOutputStream.java:155) 
~[?:1.8.0_181]
 at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) 
~[?:1.8.0_181]
 at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) 
~[?:1.8.0_181]
 at java.io.FilterOutputStream.close(FilterOutputStream.java:158) ~[?:1.8.0_181]
 at 
org.apache.thrift.transport.TIOStreamTransport.close(TIOStreamTransport.java:108)
 [libthrift-0.13.0.jar:0.13.0]
 at org.apache.thrift.transport.TSocket.close(TSocket.java:235) 
[libthrift-0.13.0.jar:0.13.0]
 at org.apache.thrift.transport.TZlibTransport.close(TZlibTransport.java:79) 
[libthrift-0.13.0.jar:0.13.0]{code}
It looks like this is because the TSocket gets used for both the input and 
output streams of TZLibTransport and this results in an attempt to close the 
same socket twice. It's possible to work around this by closing the TSocket 
directly instead of the TZlibTransport, but that isn't ideal because it results 
in confusing/fragile code (breaks the encapsulation around the TSocket and 
prevents use of a try-with-resources block on the TZLibTransport instance).
  
 That aside, Thrift is swallowing the exception without passing it up to the 
caller. IMHO a library should either:
 # catch an (expected) exception and handle it appropriately and completely, or
 # do nothing and pass the exception up to the caller.

Logging the exception as a warning then carrying on as though nothing happened 
isn't usually a good idea. In this particular case, Thrift's slf4j log output 
wasn't being captured by our application's logging setup. Because this 
exception was effectively being swallowed we weren't aware anything was amiss 
until we configured an slf4j bridge for unrelated reasons, which resulted in a 
huge large number of these Thrift warnings appearing in our logging.

 

  was:
The following Java code runs successfully, but causes Thrift to log a warning 
inside TIOStreamTransport:

 
{code:java}
    TTransport transport = new TZlibTransport(new TSocket("localhost", 8000, 
1000));
    transport.close();{code}
The warning is as follows:

 

 
{code:java}
WARN org.apache.thrift.transport.TIOStreamTransport - Error closing output 
stream.
 java.net.SocketException: Socket closed
 at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:118) 
~[?:1.8.0_181]
 at java.net.SocketOutputStream.write(SocketOutputStream.java:155) 
~[?:1.8.0_181]
 at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) 
~[?:1.8.0_181]
 at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) 
~[?:1.8.0_181]
 at java.io.FilterOutputStream.close(FilterOutputStream.java:158) ~[?:1.8.0_181]
 at 
org.apache.thrift.transport.TIOStreamTransport.close(TIOStreamTransport.java:108)
 [libthrift-0.13.0.jar:0.13.0]
 at org.apache.thrift.transport.TSocket.close(TSocket.java:235) 
[libthrift-0.13.0.jar:0.13.0]
 at org.apache.thrift.transport.TZlibTransport.close(TZlibTransport.java:79) 
[libthrift-0.13.0.jar:0.13.0]{code}
It looks like this is because the TSocket gets used for both the input and 
output streams of TZLibTransport and this results in an attempt to close the 
same socket twice. It's possible to work around this by closing the TSocket 
directly instead of the TZlibTransport, but that isn't ideal because it results 
in confusing/fragile code (breaks the encapsulation around the TSocket and 
prevents use of a try-with-resources block on the TZLibTransport instance).
 
That aside, Thrift is swallowing the exception without passing it up to the 
caller. IMHO a library should either: # catch an (expected) exception and 
handle it appropriately and completely, or
 # do nothing and pass the exception up to the caller.

Logging the exception as a warning then carrying on as though nothing happened 
isn't usually a good idea. In this particular case, Thrift's slf4j log output 
wasn't being captured by our application's logging setup. Because this 
exception was effectively being swallowed we weren't aware anything was amiss 
until we configured an slf4j bridge for unrelated reasons, which resulted in a 
huge large number of these Thrift warnings appearing in our logging.

 


> Socket closed exception when closing TZlibTransport
> ---------------------------------------------------
>
>                 Key: THRIFT-5081
>                 URL: https://issues.apache.org/jira/browse/THRIFT-5081
>             Project: Thrift
>          Issue Type: Bug
>          Components: Java - Library
>    Affects Versions: 0.13.0
>            Reporter: Chris Miller
>            Priority: Minor
>
> The following Java code runs successfully, but causes Thrift to log a warning 
> inside TIOStreamTransport:
>  
> {code:java}
>     TTransport transport = new TZlibTransport(new TSocket("localhost", 8000, 
> 1000));
>     transport.close();{code}
> The warning is as follows:
>  
>  
> {code:java}
> WARN org.apache.thrift.transport.TIOStreamTransport - Error closing output 
> stream.
>  java.net.SocketException: Socket closed
>  at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:118) 
> ~[?:1.8.0_181]
>  at java.net.SocketOutputStream.write(SocketOutputStream.java:155) 
> ~[?:1.8.0_181]
>  at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) 
> ~[?:1.8.0_181]
>  at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) 
> ~[?:1.8.0_181]
>  at java.io.FilterOutputStream.close(FilterOutputStream.java:158) 
> ~[?:1.8.0_181]
>  at 
> org.apache.thrift.transport.TIOStreamTransport.close(TIOStreamTransport.java:108)
>  [libthrift-0.13.0.jar:0.13.0]
>  at org.apache.thrift.transport.TSocket.close(TSocket.java:235) 
> [libthrift-0.13.0.jar:0.13.0]
>  at org.apache.thrift.transport.TZlibTransport.close(TZlibTransport.java:79) 
> [libthrift-0.13.0.jar:0.13.0]{code}
> It looks like this is because the TSocket gets used for both the input and 
> output streams of TZLibTransport and this results in an attempt to close the 
> same socket twice. It's possible to work around this by closing the TSocket 
> directly instead of the TZlibTransport, but that isn't ideal because it 
> results in confusing/fragile code (breaks the encapsulation around the 
> TSocket and prevents use of a try-with-resources block on the TZLibTransport 
> instance).
>   
>  That aside, Thrift is swallowing the exception without passing it up to the 
> caller. IMHO a library should either:
>  # catch an (expected) exception and handle it appropriately and completely, 
> or
>  # do nothing and pass the exception up to the caller.
> Logging the exception as a warning then carrying on as though nothing 
> happened isn't usually a good idea. In this particular case, Thrift's slf4j 
> log output wasn't being captured by our application's logging setup. Because 
> this exception was effectively being swallowed we weren't aware anything was 
> amiss until we configured an slf4j bridge for unrelated reasons, which 
> resulted in a huge large number of these Thrift warnings appearing in our 
> logging.
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to