Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7095006

getAudioInputStream has changed in Java 7 (mark/reset not supported for wav files)

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • tbd
    • 7, 8, 9
    • client-libs

      FULL PRODUCT VERSION :
      java version "1.7.0"
      Java(TM) SE Runtime Environment (build 1.7.0-b147)
      Java HotSpot(TM) 64-Bit Server VM (build 21.0-b17, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      A DESCRIPTION OF THE PROBLEM :
      Calls to javax.sound.sampled.AudioSystem.getAudioInputStream which worked in Java 6 fail in Java 7 because the underlying stream does not support Mark/Reset. This is not backwards compatible, and should be flagged in the release notes to Java 7. If it is flagged, I apologise in advance - I must have missed it. Anyway, I can see no reason for insisting that audio streams have to be markable - all the program does is make a short clip.

      I hope I have chosen the correct subtopic - there didn't seem to be one for javax.sound.

      REGRESSION. Last worked in version 6u26

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the program (you will need a short audio file in the "Sounds" directory) under both Java 6 and 7.

      I have been using NetBeans 6 to generate the JAR file. Netbeans 7 gives the same result.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      A blank panel.
      ACTUAL -
      Under Java 6 it shows a blank panel. Under Java 7 there is a program-generated error message showing the problem.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------

      package com.ptoye.Metronome1;

      import java.io.File;
      import java.io.FileInputStream;
      import java.io.IOException;
      import java.io.InputStream;
      import java.net.URI;
      import java.net.URISyntaxException;
      import java.net.URL;
      import java.util.jar.JarEntry;
      import java.util.jar.JarFile;
      import java.util.logging.Level;
      import java.util.logging.Logger;
      import javax.sound.sampled.AudioFormat;
      import javax.sound.sampled.AudioInputStream;
      import javax.sound.sampled.AudioSystem;
      import javax.sound.sampled.Clip;
      import javax.sound.sampled.DataLine;
      import javax.sound.sampled.LineUnavailableException;
      import javax.sound.sampled.UnsupportedAudioFileException;
      import javax.swing.JOptionPane;

      /**
       *
       * @author PToye
       */
      public class jfMetronome extends javax.swing.JFrame {

          /**
           * Number of positions of the metronome display. Must be odd.
           */
        
          private Clip clickClip = null;

          /** Creates new form jfMetronome */
          public jfMetronome() {
              InputStream clickInputStream = null;
              File clickSound = null;

              initComponents();

              Class thisClass = this.getClass();
              URL clickURL = thisClass.getResource("Sounds/clickmono.wav");
              URI clickURI = null;
              try {
                  clickURI = clickURL.toURI();
              } catch (URISyntaxException ex) {
                  Logger.getLogger(jfMetronome.class.getName()).log(Level.SEVERE, "URI Syntax exception", ex);
              }
              String clickScheme = clickURI.getScheme();
              if (clickScheme.equals("file")) {
                  try {
                      clickSound = new File(clickURI);
                      clickInputStream = new FileInputStream(clickSound);
                  } catch (Exception e) {
                      JOptionPane.showMessageDialog(pnlMnome, "Cannot create file from " + clickURI);
                  }

              } else if (clickScheme.equals("jar")) {
                  String clickJarFileRef = clickURI.getSchemeSpecificPart();
                  int shriekPos = clickJarFileRef.indexOf("!");
                  if (shriekPos < 0) {
                      JOptionPane.showMessageDialog(pnlMnome, "Cannot parse Jar file reference: no \"!\"");
                  } else {
                      String jarFileName = clickJarFileRef.substring(0, shriekPos);
                      String clickFileName = clickJarFileRef.substring(shriekPos + 1);
                      if (jarFileName.startsWith("file:")) {
                          jarFileName=jarFileName.substring(5);
                      }
                      if (clickFileName.startsWith("/")) {
                          clickFileName=clickFileName.substring(1);
                      }
                      JarFile jf = null;
                      try {
                          jf = new JarFile(jarFileName);
                      } catch (IOException ex) {
                          JOptionPane.showMessageDialog(pnlMnome, "Cannot get JAR file:" + jarFileName);
                      }

                      JarEntry je = jf.getJarEntry(clickFileName);
                      if (je != null) {
                          try {
                              clickInputStream = jf.getInputStream(je);
      // JOptionPane.showMessageDialog(pnlMnome, "inputStream="+clickInputStream);
                          } catch (IOException ex) {
                              JOptionPane.showMessageDialog(pnlMnome, "Cannot create input stream:" + je);
                          } catch (Exception e) {
                              JOptionPane.showMessageDialog(pnlMnome, "Exception in input stream:"+e);
                          }
                      } else {
                          JOptionPane.showMessageDialog(pnlMnome, "Cannot find file in JAR: " + clickFileName);
                      }

                  }

              }
              if (clickInputStream == null) {
                  JOptionPane.showMessageDialog(pnlMnome, "Cannot find click file");
                  System.exit(3);
              } else {
        // JOptionPane.showMessageDialog(pnlMnome, "Click file found OK: mark/reset="+clickInputStream.markSupported());
                  AudioInputStream audioInputStream = null;
                  try {
                      audioInputStream = AudioSystem.getAudioInputStream(clickInputStream);
                  } catch (UnsupportedAudioFileException ex) {
                      JOptionPane.showMessageDialog(pnlMnome, "Audio file exception "+ ex);
                      System.exit(1);
                  } catch (IOException ex) {
      // ****** THIS IS THE EXCEPTION!!!! ******
                      JOptionPane.showMessageDialog(pnlMnome, "IO exception " + ex);
                      System.exit(2);

                  }
                  AudioFormat audioFormat = audioInputStream.getFormat();
                  DataLine.Info dataLineInfo = new DataLine.Info(
                          Clip.class, audioFormat);
                  try {
                      clickClip = (Clip) AudioSystem.getLine(dataLineInfo);
                  } catch (LineUnavailableException ex) {
      // Logger.getLogger(this.class.getName()).log(Level.SEVERE, null, ex);
      // System.exit(1);
                  }
                  try {
                      clickClip.open(audioInputStream);
                  } catch (LineUnavailableException ex) {
                      JOptionPane.showMessageDialog(pnlMnome, "Click line unavailable:"+audioInputStream);
      // Logger.getLogger(TrySound.class.getName()).log(Level.SEVERE, null, ex);
                  } catch (IOException ex) {
                      JOptionPane.showMessageDialog(pnlMnome, "IO exception opening click stream"+audioInputStream);
      // Logger.getLogger(TrySound.class.getName()).log(Level.SEVERE, null, ex);
                  }
              }


          }

          /** This method is called from within the constructor to
           * initialize the form.
           * WARNING: Do NOT modify this code. The content of this method is
           * always regenerated by the Form Editor.
           */
          @SuppressWarnings("unchecked")
          // <editor-fold defaultstate="collapsed" desc="Generated Code">
          private void initComponents() {

              pnlMnome = new javax.swing.JPanel();

              FormListener formListener = new FormListener();

              setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
              setTitle("Metronome © Peter Toye");
              addWindowListener(formListener);
              getContentPane().setLayout(new javax.swing.BoxLayout(getContentPane(), javax.swing.BoxLayout.LINE_AXIS));

              pnlMnome.setBackground(new java.awt.Color(0, 0, 0));
              pnlMnome.setPreferredSize(new java.awt.Dimension(800, 600));
              pnlMnome.setLayout(null);
              getContentPane().add(pnlMnome);

              pack();
          }

          // Code for dispatching events from components to event handlers.

          private class FormListener implements java.awt.event.WindowListener {
              FormListener() {}
              public void windowActivated(java.awt.event.WindowEvent evt) {
              }

              public void windowClosed(java.awt.event.WindowEvent evt) {
              }

              public void windowClosing(java.awt.event.WindowEvent evt) {
              }

              public void windowDeactivated(java.awt.event.WindowEvent evt) {
              }

              public void windowDeiconified(java.awt.event.WindowEvent evt) {
              }

              public void windowIconified(java.awt.event.WindowEvent evt) {
              }

              public void windowOpened(java.awt.event.WindowEvent evt) {
                  if (evt.getSource() == jfMetronome.this) {
                      jfMetronome.this.formWindowOpened(evt);
                  }
              }
          }// </editor-fold>

          private void formWindowOpened(java.awt.event.WindowEvent evt) {
              if (!pnlMnome.requestFocusInWindow()) {
                  JOptionPane.showMessageDialog(this, "Cannot get focus for panel");
              }
          }

       

          /**
           * @param args the command line arguments
           */
          public static void main(String args[]) {
              java.awt.EventQueue.invokeLater(new Runnable() {

                  public void run() {
                      new jfMetronome().setVisible(true);
                  }
              });
          }
          // Variables declaration - do not modify
          private javax.swing.JPanel pnlMnome;
          // End of variables declaration
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Have not found one yet.

            serb Sergey Bylokhov
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: