title: Java error: Cannot find symbol - but method is in the data type class
body: <p>I receive the following error when trying to compile a Playlist class: </p>
  
  <pre><code> Playlist.java:164: error: cannot find symbol
       head.data.play();
              ^
    symbol:   method play()
    location: variable data of type Music
  </code></pre>
  
  <p>Music data type class: </p>
  
  <pre><code>import java.net.MalformedURLException;
  import java.net.URL;
  import javazoom.jlgui.basicplayer.BasicPlayer;
  import javazoom.jlgui.basicplayer.BasicPlayerException;
  
  public class Music extends MediaData
  {
  // Data Fields
  /** The name of the artist displayed */
  private String artist;
  /** The disk directory to a music file */
  private String mediaFilePath;
  /** Enables audio music to be played */
  private BasicPlayer player = new BasicPlayer();
  
  // Constructor for a music media type
  public Music(String t, String a)
  {
      super.setTitle(t);
      setArtist(a);
      getPlayCount();
      getMediaFilePath();
  } 
  
  // mutator and accessor methods removed for space
  
  /** Locates the media file on disk */
  public String getMediaFilePath()
  {
      mediaFilePath = System.getProperty("user.dir") + "/Music Library/" +    
                                      getArtist() + "-" + getTitle() + ".mp3";
      return mediaFilePath;
  }
  
  /** Plays a music file */
  public void play()
  {
      try 
      {
          player.open(new URL("file:///" + getMediaFilePath()));
          player.play();
      } 
      catch (BasicPlayerException | MalformedURLException e)
      {
          e.printStackTrace();
      }
     }    
   }
  </code></pre>
  
  <p>The play method in this class works fine when tested in a driver program.  However, when I try to access it from the play method in a Playlist class, where a Playlist is a double LinkedList with Music data type nodes, I get the error above:</p>
  
  <pre><code>import java.net.MalformedURLException;
  import java.net.URL;
  import javazoom.jlgui.basicplayer.BasicPlayer;
  import javazoom.jlgui.basicplayer.BasicPlayerException;
  import java.util.*;
  
  public class Playlist&lt;Music&gt; extends MediaData
  {
  // Data fields
  /** The playlist queue */
  private LinkedList&lt;Music&gt; musicList;
  /** The list head */
  private Node&lt;Music&gt; head;
  
  
  /** A Node is the building block for a single-linked list. */
  private static class Node&lt;Music&gt; 
  {
  
  // Data Fields
  
  /** The reference to the data. */
  private Music data;
  /** The reference to the next node. */
  private Node&lt;Music&gt; next;
  /** The reference to the previous node. */
  private Node&lt;Music&gt; prev;
  
  // Constructors
  /**
  * Creates a new node with null next and previous fields.
  * @param dataItem The data stored
  */
  private Node(Music dataItem)
  {
       data = dataItem;
       next = null;
       prev = null;
  }
  
  /**
   * Creates a new node that references another node.
   * @param dataItem The data stored
   * @param nodeRef The node referenced by new node
   */
      private Node(Music dataItem, Node&lt;Music&gt; prevNode)
      {
          Node&lt;Music&gt; afterPrevNode = prevNode.next;
          Node&lt;Music&gt; node = new Node(dataItem);
  
          prevNode.next = node;
          prevNode.prev = node;
  
          node.prev = prevNode;
          node.next = afterPrevNode;
      }
  } //end class Node
  
  // Constructor
  public Playlist(String t)
  {
      super.setTitle(t);
      musicList = new LinkedList&lt;Music&gt;();
  }
  
  /**
   * Adds a new node to the end of a list.
   * @param head The head of the current list
   * @param data The data for the new node
   */
  private void add(Node&lt;Music&gt; head, Music data) 
  {
      // If the list has just one element, add to it.
      if (head.next == null) 
      {
          Node&lt;Music&gt; node = new Node&lt;Music&gt;(data);
          head.next = node;
          node.prev = head;
      } 
      else 
      {
          add(head.next, data);
      }
  }
  
  /**
   * Wrapper method for adding a new node to the end of a list.
   * @param data The data for the new node
   */
  public void add(Music data) 
  {
      if (head == null) 
      {
          head = new Node&lt;Music&gt;(data);
      } 
      else 
      {
          add(head, data);
      }
  }
  
  /**
   * Wrapper method for removing a node.
   * @post The first occurrence of outData is removed.
   * @param outData The data to be removed
   * @return true if the item is removed,
   *         and false otherwise
   */
  public boolean remove(Music song)
  {
      boolean result;
      if (head == null) 
      {
          result = false;
      } 
      else 
      {
          result = remove(head.next, head, song);
      }
      return result;
  }
  
  /**
   * Removes a node from a list.
   * @post The first occurrence of outData is removed.
   * @param head The head of the current list
   * @param pred The predecessor of the list head
   * @param outData The data to be removed
   * @return true if the item is removed
   *         and false otherwise
   */
  private boolean remove(Node&lt;Music&gt; head, Node&lt;Music&gt; pred, Music song) 
  {
      boolean result;
      if (head == null)
      {
          result = false;
      } 
      else if (head.data.equals(song)) 
      {
          pred.next = head.next;
          pred.prev = null;
          head = pred;
          result = true;
      } 
      else 
      {
          result = remove(head.next, head, song);
      }
      return result;
  }
  
  /** Plays a playlist
   *    @param head The song to be played */
  private void play(Node&lt;Music&gt; head)
  {
      if (head != null)
      {
           head.data.play();
           play(head.next);
      }
  }
  
  /** Wrapper method that plays a playlist */
  public void play()
  {
      if (head != null)
      {
           head.data.play();
           play(head.next);
      }
  }
  
  public void pause()
  {
  
  }
  
  /**
   * Finds the size of a list.
   * @param head The head of the current list
   * @return The Size of the Current List
   */
  private int size(Node&lt;Music&gt; head) 
  {
      if (head == null) 
      {
          return 0;
      } 
      else 
      {
          return 1 + size(head.next);
      }
  }
  
  /**
   * Wrapper method for finding the size of a list.
   * @return The size of the list
   */
  public int size() 
  {
      return size(head);
  }
  
  /**
   * Returns the string representation of a list.
   * @param head The head of the current list
   * @return The state of the current list
   */
  private String toString(Node&lt;Music&gt; head) 
  {
      if (head == null) 
      {
          return "";
      } 
      else 
      {
          return head.data + "\n" + toString(head.next);
      }
  }
  
  /**
   * Wrapper method for returning the string representation of a list.
   * @return The string representation of the list
   */
  @Override
  public String toString() 
  {
      return toString(head);
  }
  
  /**
  * Checks if the list is empty
  * @return true if empty, false otherwise
  */
  public boolean empty()
  {
      boolean result = false;
      if (head == null)
      {
      result = true;
      }
      return result;
  }
  
  /** Adds a node before another node.
      @param prevNode The node before node
      @param node The node the item will be inserted before
      @param item The data stored in the node
  */
  public void insertBefore(Node prevNode, Music nodeData, Music data)
  {            
      if (prevNode.next.data == nodeData)
      {
          Node&lt;Music&gt; prevPrevNode = prevNode.prev;
          Node&lt;Music&gt; node = new Node&lt;Music&gt;(data);
  
          prevPrevNode.next = node;
          prevNode.prev = node;
  
          node.prev = prevNode.prev;
          node.next = prevNode;
      }
      else
      {
          insertBefore(prevNode.next, nodeData, data); 
      }
  }
  
  /** Wrapper class that adds a node before another node.
      @param node The node the item will be inserted before
      @param item The data stored in the node
  */
  public void insertBefore(Music nodeData, Music data)
  {            
      if (nodeData == head.data)
      {
          addAtHead(data);
      }
      else
      {
          insertBefore(head.next, nodeData, data); 
      }
  }
  
  /** Adds a node after another node.
      @param head The head node
      @param nodeData The node the item will be inserted before
      @param data The data stored in the node
  */
  public void insertAfter(Node head, Music nodeData, Music data)
  {            
      if (nodeData == head.data)
      {
          Node&lt;Music&gt; node = new Node&lt;Music&gt;(data);
          Node&lt;Music&gt; afterHead = head.next;
  
          node.next = afterHead.next;
          head.next = node;
          node.prev = head;
          afterHead.prev = node;
      }
      else
      {
          insertAfter(head.next, nodeData, data); 
      }
  }
  
  /** Wrapper class that adds a node after another node.
      @param nodeData The node the item will be inserted after
      @param data The data stored in the node
  */
  public void insertAfter(Music nodeData, Music data)
  {
      insertAfter(head, nodeData, data); 
  }
  
  /** Adds a node to the front of the list
   *    @param head The front of the list
   *    @param Music The data added
   */
  public void addAtHead(Music data)
  {
      if (empty())
      {
          head = new Node&lt;Music&gt;(data);
      }
      else
      {
          Node&lt;Music&gt; node = head;
          head = new Node&lt;Music&gt;(data);
          head.next = node;
          node.prev = head;
      }
  }
  
  /** Adds a node to the list
   *    @param head The front of the list
   *    @param Music The data added
   */
  public void addAtEnd(Node head, Music data)
  {
      Node&lt;Music&gt; node;
      if (head.next == null)
      {
          node = new Node&lt;Music&gt;(data);
          head.next = node;
          node.prev = head;
      }
      else
      {
          node = head.next;
          addAtEnd(node, data);
      }
  }
  
  /** Wrapper method to add a node to the list
   *    @param Music The data added
   */
  public void addAtEnd(Music data)
  {
      if (empty())
      {
          head = new Node&lt;Music&gt;(data);
      }
      else
      {
          addAtEnd(head, data);
      }
  }
  
  /**
  * Return the data of the first Node
  * @return The data of the first Node
  */
  public Music peekFront()
  {
      Music m;
      if (empty()) 
      {
          m = null;
      } 
      else 
      {
          m = head.data;
      }
      return m;
  }
  
  /**
  * Return the data of the last Node
  * @return The data of the last Node
  */
  
  public Music peekEnd(Node&lt;Music&gt; head)
  {
      Music m;
      if (head.next != null)
      {
          Node&lt;Music&gt; node = head.next;
          peekEnd(node);
          m = node.data;
      }
      else
      {
          m = head.data;
      }
  
      return m;
  }
  
  /**
  * Wrapper method for the data of the last Node
  * @return The data of the last Node
  */
  
  public Music peekEnd()
  {
      Music m;
      if (head == null)
      {
          m = null;
      } 
      else 
      {
          m = peekEnd(head);
      }
      return m;
  }
  
  /** Remove the first node from the list
      @returns The data from the removed node, or null if the list is empty
  */
  public Music removeFront()
  {
      Music m = null;
      Node&lt;Music&gt; temp = head;
      Node&lt;Music&gt; afterHead = head.next;
      if (head != null)
      {
          m = temp.data;
          head = head.next;
          afterHead.prev = head;
  
      }
      return m;
  }
  
  /** Remove the last node from the list
   * @param head The head of the current list
   * @return The data from the removed node, or null if the list is empty
   */
  public Music removeEnd(Node&lt;Music&gt; head)
  {
      Music m;
      if (head.next != null)
      {
          Node&lt;Music&gt; node = head.next;
          removeEnd(node);
          m = node.data;
          node.next = null;
      }
      else
      {
          m = head.data;
          head = null;
      }
  
      return m;
   }
  
  /**
   * Wrapper method for removing the last Node
   * @return The data from the removed node, or null if the list is empty
   */
  public Music removeEnd()
  {
      Music m;
      if (head == null)
      {
          m = null;
      } 
      else 
      {
          m = removeEnd(head);
      }
      return m;
   }
  
   } // End of class
  </code></pre>
  
  <p>There is a play method in the Music class, so I don't understand why I'm getting this error.  A previous version (where the playlist was not implemented as a LinkedList) of this class did not have this issue.  Please advise how to remedy</p>