<Sound Dev> Comment on bug JDK-8013586

Sergey Bylokhov Sergey.Bylokhov at oracle.com
Thu Jul 16 19:26:23 UTC 2015


Hi, Everybody.
On 10.01.15 1:09, Florian Bomers wrote:
> At the time, I've fixed the same type of bug in WaveFileReader and the
> likes. It was tracked under bug #4325421 and I *should* have written a
> unit test. If indeed,  you should find it by looking for a unit test
> with that bug id.
>
> In WaveFileReader, I fixed it without a clumsy catch clause --
> analogous to this:
>
>    FileInputStream fis = new FileInputStream(file);
>    BufferedInputStream bis = new BufferedInputStream(fis);
>    AudioInputStream ais = null;
>    try {
>      ais = getAudioInputStream(bis);
>    } finally {
>      if (ais == null) {
>        bis.close();
>      }
>    }
>    return ais;
In this example if getAudioInputStream() will throw 
UnsupportedAudioFileException and the last close() method will throw 
IOException, then we will not check the next audio reader.
I have a small prototype where I merge all implementations of 
getAudioXXX to the SunFileReader. It will fix this and related issues:
http://cr.openjdk.java.net/~serb/8013586/webrev.01
Issues which were fixed:
  - Streams were not closed when necessary. In the fix they are closed 
always in case of any exceptions. JDK-8013586
  - Some of the readers do not reset the streams when they throw an 
UnsupportedAudioFileException exception. JDK-8130305
  - Some of the readers(like AiffFileReader) do not wrap 
(FileInputStream, etc) in BufferedInputStream.

I assume that this fix should not cause regressions so I will send a 
review request for it as is, after the testing. I found some other small 
issues(like handling EOFException) in this code but will fix it 
separately later.

Also I have a related question about WaveExtensibleFileReader why it was 
not added to the spi.AudioFileReader? Because of this 
WaveExtensibleFileReader actually is never used.

Best, Florian On 09.01.2015 20:21, Dan Rollo wrote:
>> Yikes, Good point Klaus! Forgot the caller wants to actually use a
>> valid stream for the non-exceptional case. Would have to move the
>> is.close() back into a catch clause. I’ll try to post a better one
>> later. (Any unit tests of this sort of thing exist in the tree now? -
>> if not, I could try a unit test too).
>>
>>> On Jan 9, 2015, at 12:34 PM, Klaus Jaensch
>>> <klausj at phonetik.uni-muenchen.de
>>> <mailto:klausj at phonetik.uni-muenchen.de>> wrote:
>>>
>>> Hi Dan,
>>>
>>> Am 09.01.2015 um 05:37 schrieb Dan Rollo:
>>>> Even better, no need for the “catch/throw” chunk, because the
>>>> method declares those caught exceptions:
>>>>
>>>>
>>>> public AudioInputStream getAudioInputStream(File file)
>>>>          throws UnsupportedAudioFileException, IOException {
>>>>
>>>>      final FileInputStream fis = new FileInputStream(file);
>>>>      try {
>>>>          return getAudioInputStream(new BufferedInputStream(fis));
>>>>      } finally {
>>>>          fis.close();
>>>>      }
>>>> }
>>> I think your code will not work. If the call to
>>> getAudioInputStream(InputStream) succeeds the code always closes the
>>> stream before it is returned.
>>>
>>>
>>> I suggest this approach:
>>>
>>> public AudioInputStream getAudioInputStream(File file)
>>>              throws UnsupportedAudioFileException, IOException {
>>>          FileInputStream fis=new FileInputStream(file);
>>>          BufferedInputStream bis=new BufferedInputStream(fis);
>>>          AudioInputStream ais=null;
>>>          try{
>>>              ais=getAudioInputStream(bis);
>>>          } catch(IOException|UnsupportedAudioFileException e) {
>>>              if(bis!=null){
>>>                  bis.close();
>>>              }
>>>              throw e;
>>>          }
>>>          return ais;
>>>      }
>>>
>>> Closes the BufferedInputStream as well as the underlying
>>> FileInputStream.
>>>
>>> I think the method:
>>> public AudioInputStream getAudioInputStream(URL url)
>>>
>>> needs to be changed in the same way.
>>>
>>>
>>> Best regards,
>>> Klaus
>>>
>>>
>>>>
>>>>> On Jan 7, 2015, at 11:41 PM, Dan Rollo <danrollo at gmail.com
>>>>> <mailto:danrollo at gmail.com>> wrote:
>>>>>
>>>>> If this approach is taken, I’d like to suggest using a ‘final’ var
>>>>> instead of ‘null init/null check’, for example:
>>>>>
>>>>> public AudioInputStream getAudioInputStream(File file)
>>>>>          throws UnsupportedAudioFileException, IOException {
>>>>>
>>>>>      final FileInputStream fis = new FileInputStream(file);
>>>>>      try {
>>>>>          return getAudioInputStream(new BufferedInputStream(fis));
>>>>>      } catch(IOException|UnsupportedAudioFileException e) {
>>>>>          throw e;
>>>>>      } finally {
>>>>>          fis.close();
>>>>>      }
>>>>> }
>>>>>
>>>>>
>>>>>> On Jan 7, 2015, at 10:51 PM, Sergey Bylokhov
>>>>>> <Sergey.Bylokhov at oracle.com <mailto:Sergey.Bylokhov at oracle.com>>
>>>>>> wrote:
>>>>>>
>>>>>> On 08.01.2015 1:13, Phil Race wrote:
>>>>>>> Its not clear to me if the bug description is implying an
>>>>>>> exception was thrown
>>>>>> UnsupportedAudioFileException is thrown if the URL/File does not
>>>>>> point to valid audio file data recognized by the specific reader,
>>>>>> so AudioSystem will try to move to the next reader and a leak
>>>>>> will occur.
>>>>>> Actually most of our readers are affected.
>>>>>>> Still, something like what you suggest seems to be needed.
>>>>>> right.
>>>>>>> The owner of this bug is out until next week so I'll let him
>>>>>>> comment further
>>>>>>> after his return.
>>>>>>>
>>>>>>> -phil.
>>>>>>>
>>>>>>> On 01/07/2015 12:42 PM, Mike Clark wrote:
>>>>>>>> Hello all,
>>>>>>>>
>>>>>>>> I wanted to post this as a comment
>>>>>>>> on https://bugs.openjdk.java.net/browse/JDK-8013586, but
>>>>>>>> apparently getting comment access to that system is a bit of a
>>>>>>>> hurdle.  Anyway.  What follows is, I believe, a fix for the
>>>>>>>> aforementioned bug:
>>>>>>>>
>>>>>>>> There is a file handle leak in some of the subclasses of
>>>>>>>> javax.sound.sampled.spi.AudioFileReader, such as
>>>>>>>> com.sun.media.sound.WaveFloatFileReader.
>>>>>>>>
>>>>>>>> Consider com.sun.media.sound.WaveFloatFileReader's method:
>>>>>>>>
>>>>>>>> public AudioInputStream getAudioInputStream(File file)
>>>>>>>>          throws UnsupportedAudioFileException, IOException {
>>>>>>>>      return getAudioInputStream(
>>>>>>>>          new BufferedInputStream(new FileInputStream(file)));
>>>>>>>> }
>>>>>>>>
>>>>>>>> See how there is no attempt to close the FileInputStream if an
>>>>>>>> exception is thrown?  A file handle will remain open on the
>>>>>>>> file until garbage collection is run. Since garbage collection
>>>>>>>> may never run, the file handle may remain open until the JVM
>>>>>>>> exits. And on Windows the open file handle prevents the file
>>>>>>>> from being deleted, which is problematic.
>>>>>>>>
>>>>>>>> Could we fix it by adding a try/catch block?
>>>>>>>>
>>>>>>>> public AudioInputStream getAudioInputStream(File file)
>>>>>>>>          throws UnsupportedAudioFileException, IOException {
>>>>>>>>      FileInputStream fis = null;
>>>>>>>>      try {
>>>>>>>>          fis = new FileInputStream(file);
>>>>>>>>          return getAudioInputStream(new BufferedInputStream(fis));
>>>>>>>>      } catch(IOException|UnsupportedAudioFileException e) {
>>>>>>>>          if (fis != null) {
>>>>>>>>              fis.close();
>>>>>>>>          }
>>>>>>>>          throw e;
>>>>>>>>      }
>>>>>>>> }
>>>>>>>>
>>>>>>>> These AudioFileReader subclass methods are usually called by
>>>>>>>> javax.sound.sampled.AudioSystem.getAudioInputStream(File),
>>>>>>>> which calls getAudioInputStream(File) on all registered
>>>>>>>> subclasses of AudioFileReader.  As such, all subclasses of
>>>>>>>> AudioFileReader in the JRE should be reviewed for this problem.
>>>>>>>>
>>>>>>>> best regards,
>>>>>>>> -Mike
>>>>>>>>
>>>>>>
>>>>>> -- 
>>>>>> Best regards, Sergey.
>>>
>>> -- 
>>> ------------------------------------------
>>> Klaus Jaensch
>>> Muenchen
>>> Germany
>>>
>>> Institut fuer Phonetik und Sprachverarbeitung
>>> Schellingstr.3/II
>>> Room 223 VG
>>> 80799 München
>>>
>>> Phone (Work): +49-(0)89-2180-2806
>>> Fax:          +49-(0)89-2180-5790
>>> EMail: klausj at phonetik.uni-muenchen.de


-- 
Best regards, Sergey.



More information about the sound-dev mailing list