Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 395977 - [compiler][resource] Resource leak warning behavior possibly incorrect for anonymous inner class
Summary: [compiler][resource] Resource leak warning behavior possibly incorrect for an...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.2.1   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 4.3 M4   Edit
Assignee: Stephan Herrmann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-12-06 14:34 EST by Colin Bartolome CLA
Modified: 2012-12-11 04:12 EST (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Colin Bartolome CLA 2012-12-06 14:34:33 EST
With the "resource leak" and "potential resource leak" warnings turned on and the source compliance set to 1.7, the below code exhibits some odd behavior. When I declare an anonymous inner class, a "Resource leak: (unassigned Closeable value) is never closed" warning appears. When I remove the anonymous inner class, no warning appears.

It seems like the warning should appear for both cases or for neither case. I'm also not sure how the compiler expects me to fix the warning.

Here's the code:

import java.io.*;

public class WriterTest implements Runnable
{
   private BufferedWriter m_Writer;
   
   @Override
   public void run()
   {
      try
      {
         initializeWriter();
         
         m_Writer.write("string");
         m_Writer.newLine();
         
         closeWriter();
      }
      catch (IOException ioe)
      {
         ioe.printStackTrace();
      }
   }
   
   private void initializeWriter()
      throws UnsupportedEncodingException, FileNotFoundException
   {
      m_Writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("file"), "UTF-8"))
      {
         /**
          * Writes an LF character on all platforms, to avoid constantly flipping the line terminator style.
          */
         @Override
         public void newLine() throws IOException
         {
            write('\n');
         }
      };
   }
   
   private void closeWriter()
      throws IOException
   {
      m_Writer.close();
   }
}
Comment 1 Stephan Herrmann CLA 2012-12-06 18:35:29 EST
Thanks for the report. I could directly use your example as a test case which demonstrates a trivial omission in the code: when creating a binding for the anonymous class we forgot to mark it as a wrapper closeable, so the anonymous class wasn't included in the leak analysis at all.
Comment 2 Stephan Herrmann CLA 2012-12-07 17:46:11 EST
At a closer look this case is quite special:

If you directly use BufferedWriter, the compiler knows qua its whitelist that this is a "resource wrapper" with these properties:
1. it holds on to the first constructor argument, which again is a resource
2. it delegates close() calls to the wrapped resource.

When sub-classing BufferedWriter the compiler cannot know whether the subclass also fulfills both conditions.

For an anonymous sub-class we know that at least (1) holds, so I'm inclined to assuming that also (2) should normally hold -- might as well check if the anonymous class overrides close().
Comment 3 Stephan Herrmann CLA 2012-12-07 17:49:23 EST
More testing in this area revealed why the issue is reported as a definite leak, not a potential one:
Code in QualifiedAllocationExpression missed a small change (different order of statements) that was made in AllocationExpression.
I'll include a fix for that part, too, to the effect that the analysis will see that the inner resource is passed as an argument to the ctor call, so we don't definitely know what'll happen to the resource.
Comment 4 Stephan Herrmann CLA 2012-12-07 18:05:18 EST
Released for 4.3 M4 via commit 089badac3a8a0209e6db9e45831031dae9c203f2.
Comment 5 Jay Arthanareeswaran CLA 2012-12-11 04:12:25 EST
Verified for 4.3 M4 with build I20121210-2000.