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

Antonio García updated THRIFT-3392:
-----------------------------------
    Description: 
While setting up a short demo project using the new Java TZlibTransport in 
0.9.3, I wrote code like this:

{code:java}
try (TProtocol proto = new TJSONProtocol(new TZlibTransport(...))) {
  Blog blog = new Blog();
  // set up fields in blog
  proto.write(blog);
}
{code}

However, when I went to look at the file, I found it mostly empty (with only 
the header bytes). I had a look at the TZlibTransport code, which seems to be a 
subclass of TIOStreamTransport that wraps its underlying transport using Java 
inflater/deflater streams:

{code:java}
public TZlibTransport(TTransport transport, int compressionLevel) {
  transport_ = transport;
  inputStream_ = new InflaterInputStream(new TTransportInputStream(transport_), 
new Inflater());
  outputStream_ = new DeflaterOutputStream(new 
TTransportOutputStream(transport_), new Deflater(compressionLevel, false), 
true);
}
{code}

However, on its close method it only closes the transport and not the 
underlying streams, forcing users to flush the transport before closing if they 
really want to write everything:

{code:java}
public void close() {
      if (transport_.isOpen()) {
          transport_.close();
}
{code}

I think it would be better if we simply relied on the close() method of the 
TIOStreamTransport, which closes the input and output streams if they have been 
created. Additionally, it would be better to create the input stream on the 
first read and the output stream on the first write: otherwise, we will get an 
error during closing if we're only reading (as TIOStreamTransport will still 
try to close the output side, resulting in writes from the deflater).

I have a first version of a fix for these issues: I'll turn it into a pull 
request on Github.

  was:
While setting up a short demo project using the new Java TZlibTransport in 
0.9.3, I wrote code like this:

try (TProtocol proto = new TJSONProtocol(new TZlibTransport(...))) {
  Blog blog = new Blog();
  // set up fields in blog
  proto.write(blog);
}

However, when I went to look at the file, I found it mostly empty (with only 
the header bytes). I had a look at the TZlibTransport code, which seems to be a 
subclass of TIOStreamTransport that wraps its underlying transport using Java 
inflater/deflater streams:

 public TZlibTransport(TTransport transport, int compressionLevel) {
         transport_ = transport;
        inputStream_ = new InflaterInputStream(new 
TTransportInputStream(transport_), new Inflater());
        outputStream_ = new DeflaterOutputStream(new 
TTransportOutputStream(transport_), new Deflater(compressionLevel, false), 
true);
     }

However, on its close method it only closes the transport and not the 
underlying streams, forcing users to flush the transport before closing if they 
really want to write everything:

  public void close() {
        if (transport_.isOpen()) {
            transport_.close();
  }

I think it would be better if we simply relied on the close() method of the 
TIOStreamTransport, which closes the input and output streams if they have been 
created. Additionally, it would be better to create the input stream on the 
first read and the output stream on the first write: otherwise, we will get an 
error during closing if we're only reading (as TIOStreamTransport will still 
try to close the output side, resulting in writes from the deflater).

I have a first version of a fix for these issues: I'll turn it into a pull 
request on Github.


> Java TZlibTransport does not close its wrapper streams upon close()
> -------------------------------------------------------------------
>
>                 Key: THRIFT-3392
>                 URL: https://issues.apache.org/jira/browse/THRIFT-3392
>             Project: Thrift
>          Issue Type: Bug
>          Components: Java - Library
>    Affects Versions: 0.9.3
>            Reporter: Antonio García
>
> While setting up a short demo project using the new Java TZlibTransport in 
> 0.9.3, I wrote code like this:
> {code:java}
> try (TProtocol proto = new TJSONProtocol(new TZlibTransport(...))) {
>   Blog blog = new Blog();
>   // set up fields in blog
>   proto.write(blog);
> }
> {code}
> However, when I went to look at the file, I found it mostly empty (with only 
> the header bytes). I had a look at the TZlibTransport code, which seems to be 
> a subclass of TIOStreamTransport that wraps its underlying transport using 
> Java inflater/deflater streams:
> {code:java}
> public TZlibTransport(TTransport transport, int compressionLevel) {
>   transport_ = transport;
>   inputStream_ = new InflaterInputStream(new 
> TTransportInputStream(transport_), new Inflater());
>   outputStream_ = new DeflaterOutputStream(new 
> TTransportOutputStream(transport_), new Deflater(compressionLevel, false), 
> true);
> }
> {code}
> However, on its close method it only closes the transport and not the 
> underlying streams, forcing users to flush the transport before closing if 
> they really want to write everything:
> {code:java}
> public void close() {
>       if (transport_.isOpen()) {
>           transport_.close();
> }
> {code}
> I think it would be better if we simply relied on the close() method of the 
> TIOStreamTransport, which closes the input and output streams if they have 
> been created. Additionally, it would be better to create the input stream on 
> the first read and the output stream on the first write: otherwise, we will 
> get an error during closing if we're only reading (as TIOStreamTransport will 
> still try to close the output side, resulting in writes from the deflater).
> I have a first version of a fix for these issues: I'll turn it into a pull 
> request on Github.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to