Skip to content

Commit

Permalink
[FIXED JENKINS-20610] symlink FileAlreadyExistsException
Browse files Browse the repository at this point in the history
Retrying 3 times while waiting for 100 millis between retries (at
recreating symlink after "deleting" it). Ends up throwing FAE exception
if thrown for a 4th time in a row - as not much can be done at that
point. A warning is logged in that case, prior to throwing the last FAE.
  • Loading branch information
marco-miller committed Nov 15, 2013
1 parent 48efa73 commit d0f84c2
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions core/src/main/java/hudson/Util.java
Expand Up @@ -62,6 +62,7 @@
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand Down Expand Up @@ -1136,9 +1137,28 @@ private static boolean createSymlinkJava7(File baseDir, String targetPath, Strin
Object target = Class.forName("java.nio.file.Paths").getMethod("get", String.class, String[].class).invoke(null, targetPath, new String[0]);
Class<?> filesC = Class.forName("java.nio.file.Files");
Class<?> pathC = Class.forName("java.nio.file.Path");
filesC.getMethod("deleteIfExists", pathC).invoke(null, path);
Class<?> fileAlreadyExistsExceptionC = Class.forName("java.nio.file.FileAlreadyExistsException");

Object noAttrs = Array.newInstance(Class.forName("java.nio.file.attribute.FileAttribute"), 0);
filesC.getMethod("createSymbolicLink", pathC, pathC, noAttrs.getClass()).invoke(null, path, target, noAttrs);
final int maxNumberOfTries = 4;
final int timeInMillis = 100;
for (int tryNumber = 1; tryNumber <= maxNumberOfTries; tryNumber++) {
filesC.getMethod("deleteIfExists", pathC).invoke(null, path);
try {
filesC.getMethod("createSymbolicLink", pathC, pathC, noAttrs.getClass()).invoke(null, path, target, noAttrs);
break;
}
catch (Exception x) {
if (fileAlreadyExistsExceptionC.isInstance(x)) {
if(tryNumber < maxNumberOfTries) {
TimeUnit.MILLISECONDS.sleep(timeInMillis); //trying to defeat likely ongoing race condition
continue;
}
LOGGER.warning("symlink FileAlreadyExistsException thrown "+maxNumberOfTries+" times => cannot createSymbolicLink");
}
throw x;
}
}
return true;
} catch (NoSuchMethodException x) {
return false; // fine, Java 6
Expand Down

0 comments on commit d0f84c2

Please sign in to comment.