title: Where is the JVM holding my file lock?
body: <p>I am dealing with a java.nio.file.AccessDeniedException problem.</p>
  
  <p>I have a Scala program where if I do:</p>
  
  <pre><code>java.nio.file.Files.delete(FileSystems.getDefault().getPath("""D:\Users\Eric\Google Drive (New)\Music\Downloaded\Foreigner [Discography HQ]\1977 - Foreigner\03 - Starrider.mp3""")) 
  </code></pre>
  
  <p>Everything works fine. I have some code where I do</p>
  
  <pre><code>def delete(path : Path) {
    try {
      println("deleting " + path)
      java.nio.file.Files.delete(path)
    } catch {
      case exception: Exception =&gt; System.err.println(exception)
    }
  }
  
  val google1 = FileSystems.getDefault().getPath("""D:\Users\Eric\Google Drive\Music\Downloaded\Foreigner [Discography HQ]""")
  val google2 = FileSystems.getDefault().getPath("""D:\Users\Eric\Google Drive (New)\Music\Downloaded\Foreigner [Discography HQ]""")
  
  val duplicates = TraversablePaths(List(google1, google2)).duplicateFilesList
  
  println("deleting duplicate files")
  duplicates.foreach(_.filter(!_.startsWith(google1)).foreach(delete))
  </code></pre>
  
  <p>But when I try to delete the same file, I get</p>
  
  <pre><code>java.nio.file.AccessDeniedException: D:\Users\Eric\Google Drive (New)\Music\Downloaded\Foreigner [Discography HQ]\1977 - Foreigner\03 - Starrider.mp3
  </code></pre>
  
  <p>The best I can tell is that the JVM is either holding a lock on the file or the directory the file is in, but I cannot figure out where. The code that checks to see if files are identical looks like</p>
  
  <pre><code>def identical(file1 : Path, file2 : Path) : Boolean = {
  
    require(isRegularFile(file1), file1 + " is not a file")
    require(isRegularFile(file2), file2 + " is not a file")
  
    val size1 = size(file1)
    val size2 = size(file2)
  
    if (size1 != size2) return false
  
    var position : Long = 0
    var length = min(Integer.MAX_VALUE, size1 - position)
  
    val channel1 = FileChannel.open(file1)
    val channel2 = FileChannel.open(file2)
  
    try {
      while (length &gt; 0) {
        val buffer1 = channel1.map(MapMode.READ_ONLY, position, length)
        val buffer2 = channel2.map(MapMode.READ_ONLY, position, length)
        if (!buffer1.equals(buffer2)) return false
          position += length
      length = min(Integer.MAX_VALUE, size1 - position)
      }
      true
      } finally {
      channel1.close()
      channel2.close()
    }
  }
  </code></pre>
  
  <p>I would have thought that closing the channels would free any file locks the JVM needs. This is the only part of the code where I actually open the files for reading, although other parts of the code do check the file lengths, but I would not expect the JVM to need a file lock for that.</p>
  
  <p>What other reasons would the JVM be holding file locks? How can I find out, and how can I free them?</p>
  
  <p>Cheers, Eric</p>