title: How to avoid java.nio.file.AccessDeniedException when using java.nio.file.Files.move()?
body: <p>My Java program (see below) sometimes crashes with a java.nio.file.AccessDeniedException in a java.nio.File.move() method execution.</p>
  
  <p>I could not understand why this exception is thrown and I have no bypass for now.</p>
  
  <p>Here is an example of the exception :</p>
  
  <pre><code>java.nio.file.AccessDeniedException: C:\PROJECTS\PROJECT0\CHANGES -&gt; C:\PROJECTS\PROJECT0\GEN70\CHANGES
      at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:95)
      at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:109)
      at sun.nio.fs.WindowsFileCopy.move(WindowsFileCopy.java:399)
      at sun.nio.fs.WindowsFileSystemProvider.move(WindowsFileSystemProvider.java:299)
      at java.nio.file.Files.move(Files.java:1406)
      at com.ibm.cldt.engine.tool.TestMove.generate(TestMove.java:75)
      at com.ibm.cldt.engine.tool.TestMove.createAndUseProject(TestMove.java:42)
      at com.ibm.cldt.engine.tool.TestMove.main(TestMove.java:25)
  </code></pre>
  
  <p>Here the problem is detected on "GEN70" of "PROJECT0", but, it varies. For example, here is another run :
  java.nio.file.AccessDeniedException: C:\PROJECTS\PROJECT2\CHANGES -> C:\PROJECTS\PROJECT2\GEN33\CHANGES</p>
  
  <p>Note : before running the program, you have to delete the directory C:/PROJECTS if you have one.</p>
  
  <p>What can I do to prevent my program from throwing this exception ?</p>
  
  <p>I run this code on Windows 10 Enterprise, and an IBM JRE 1.8.</p>
  
  <pre><code>java version "1.8.0"
  Java(TM) SE Runtime Environment (build pwa6480sr4fp5-20170421_01(SR4 FP5))
  IBM J9 VM (build 2.8, JRE 1.8.0 Windows 10 amd64-64 Compressed References 20170419_344392 (JIT enabled, AOT enabled)
  J9VM - R28_20170419_1004_B344392
  JIT  - tr.r14.java_20170419_344392
  GC   - R28_20170419_1004_B344392_CMPRSS
  J9CL - 20170419_344392)
  JCL - 20170420_01 based on Oracle jdk8u131-b11
  </code></pre>
  
  <p>Here is the code. You can run it as Java standalone application. Before launching, check that you do not have a C:/PROJECTS directory.</p>
  
  <p>I will be surprised if the program execution ends without exception on your machine. If that is the case, please retry ...</p>
  
  <pre><code>import java.io.BufferedReader;
  import java.io.BufferedWriter;
  import java.io.IOException;
  import java.nio.file.Files;
  import java.nio.file.Path;
  import java.nio.file.Paths;
  import java.nio.file.StandardOpenOption;
  
  public class TestMove
  {
      private static final String PROJECTS_ROOT = "C:/PROJECTS";
      private static final int NUMBER_OF_PROJECTS = 10;
      private static final int NUMBER_OF_GENERATIONS = 100;
      private static final int NUMBER_OF_CHANGES = 10;
  
  
      public static void main( String[] args )
      {
          try
          {
              for ( int project = 0; project &lt; NUMBER_OF_PROJECTS; ++project )
              {
                  createAndUseProject( "PROJECT"+project );
              }
          }
          catch ( IOException ioe )
          {
              ioe.printStackTrace();
          }
      }
  
  
      private static void createAndUseProject( String projectName ) throws IOException
      {
          Path projectRoot = Paths.get( PROJECTS_ROOT, projectName );
          Files.createDirectories( projectRoot );
          for ( int generation = 0; generation &lt; NUMBER_OF_GENERATIONS; ++generation )
          {
              addNewChanges( projectRoot );
              generate( projectRoot, generation );
          }
      }
  
  
      private static final StandardOpenOption[] CREATE_APPEND =
          new StandardOpenOption[] { StandardOpenOption.CREATE, StandardOpenOption.APPEND };
  
  
      private static void addNewChanges( Path projectRoot ) throws IOException
      {
          Path changesDir = projectRoot.resolve( "CHANGES" );
          Files.createDirectory( changesDir );
          String newLine = System.lineSeparator();
          Path changesLogFile = changesDir.resolve( "changes.log" );
          try ( BufferedWriter changesWriter = Files.newBufferedWriter( changesLogFile, CREATE_APPEND ) )
          {
              for ( int change = 0; change &lt; NUMBER_OF_CHANGES; ++change )
              {
                  changesWriter.append( "This is my change number "+ change ).append( newLine );
              }
          }
      }
  
  
      private static void generate( Path projectRoot, int generation ) throws IOException
      {
          Path generationDir = projectRoot.resolve( "GEN"+generation );
          Files.createDirectory( generationDir );
          Path projectChangesDir = projectRoot.resolve( "CHANGES" );
          Path generationChangesDir = generationDir.resolve( "CHANGES" );
  
          // Here is the problem : AccessDeniedException is thrown ... sometimes.
          Files.move( projectChangesDir, generationChangesDir );
  
          Path changesLogFile = generationChangesDir.resolve( "changes.log" );
          try ( BufferedReader changesReader = Files.newBufferedReader( changesLogFile ) )
          {
              for ( String change = changesReader.readLine(); change != null; change = changesReader.readLine() )
                  computeChange( change );
          }
      }
  
  
      private static void computeChange( String change )
      {
          // Do whatever needed ...
      }
  }
  </code></pre>
  
  <p>What can I do to prevent my program from throwing this exception ?</p>
  
  <p>COMPLEMENTS
  From the first answers, I downloaded the Oracle JDK 1.8.0_221 from Oracle website. Then, I used javac and java commands to compile and run my program from a CMD window.
  Here is the transcript:</p>
  
  <pre><code>Microsoft Windows [Version 10.0.18362.356]
  (c) 2019 Microsoft Corporation. All rights reserved.
  
  C:\tmp\Java&gt;dir
   Volume in drive C is Windows
   Volume Serial Number is 8A56-3036
  
   Directory of C:\tmp\Java
  
  09/24/2019  06:57 PM    &lt;DIR&gt;          .
  09/24/2019  06:57 PM    &lt;DIR&gt;          ..
  09/24/2019  06:54 PM             2,678 TestMove.java
                 1 File(s)          2,678 bytes
                 2 Dir(s)  353,415,393,280 bytes free
  
  C:\tmp\Java&gt;"C:\Program Files\Java\jdk1.8.0_221\bin\javac" TestMove.java
  
  C:\tmp\Java&gt;"C:\Program Files\Java\jdk1.8.0_221\bin\java" TestMove
  java.nio.file.AccessDeniedException: C:\PROJECTS\PROJECT0\CHANGES -&gt; C:\PROJECTS\PROJECT0\GEN97\CHANGES
          at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83)
          at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
          at sun.nio.fs.WindowsFileCopy.move(WindowsFileCopy.java:387)
          at sun.nio.fs.WindowsFileSystemProvider.move(WindowsFileSystemProvider.java:287)
          at java.nio.file.Files.move(Files.java:1395)
          at TestMove.generate(TestMove.java:73)
          at TestMove.createAndUseProject(TestMove.java:40)
          at TestMove.main(TestMove.java:23)
  
  C:\tmp\Java&gt;
  </code></pre>
  
  <p>Same problem with a standard up-to-date JVM, an no eclipse. I feel bad ;-) ...</p>
  
  <p>UPDATE :
  I have found this bypass. It works well, but I do not feel good with it in my app in production.
  I have replaced those two lines :</p>
  
  <pre><code>// Here is the problem : AccessDeniedException is thrown ... sometimes.
  Files.move( projectChangesDir, generationChangesDir );
  </code></pre>
  
  <p>With this code:</p>
  
  <pre><code>while ( true )
  {
      try
      {
          Files.move( projectChangesDir, generationChangesDir );
          break;
      }
      catch ( IOException ioe ) { ++failures; }
  }
  </code></pre>
  
  <p>It works suprisingly well and makes it possible for my program to run until its normal end. But ... well ... not so satisfactory. At the end failures counter is around 10, sometimes less, sometimes more, for a total of 1000 attempts (10 projects x 100 generations).</p>