slub.team team mailing list archive
-
slub.team team
-
Mailing list archive
-
Message #00221
[Merge] lp:~slub.team/goobi-production/bug-988813 into lp:goobi-production
Ralf Claussnitzer has proposed merging lp:~slub.team/goobi-production/bug-988813 into lp:goobi-production.
Requested reviews:
Henning Gerhardt (henning-gerhardt)
Related bugs:
Bug #988813 in Goobi.Production: "Renaming of files sometimes fails"
https://bugs.launchpad.net/goobi-production/+bug/988813
For more details, see:
https://code.launchpad.net/~slub.team/goobi-production/bug-988813/+merge/105207
Reconciled with master branch. Uses FilesystemHelper class for file renaming.
--
https://code.launchpad.net/~slub.team/goobi-production/bug-988813/+merge/105207
Your team Saxon State Library Team is subscribed to branch lp:goobi-production.
=== modified file 'src/de/sub/goobi/beans/Prozess.java'
--- src/de/sub/goobi/beans/Prozess.java 2012-05-08 11:14:41 +0000
+++ src/de/sub/goobi/beans/Prozess.java 2012-05-09 13:36:18 +0000
@@ -58,6 +58,7 @@
import de.sub.goobi.persistence.BenutzerDAO;
import de.sub.goobi.persistence.ProzessDAO;
import de.sub.goobi.config.ConfigMain;
+import de.sub.goobi.helper.FilesystemHelper;
import de.sub.goobi.helper.Helper;
import de.sub.goobi.helper.enums.MetadataFormat;
import de.sub.goobi.helper.enums.StepStatus;
@@ -727,17 +728,6 @@
return result;
}
- private void renameMetadataFile(String oldFileName, String newFileName) {
- File oldFile;
- File newFile;
-
- if (oldFileName != null && newFileName != null) {
- oldFile = new File(oldFileName);
- newFile = new File(newFileName);
- oldFile.renameTo(newFile);
- }
- }
-
private String getTemporaryMetadataFileName(String fileName) {
File temporaryFile = new File(fileName);
String directoryPath = temporaryFile.getParentFile().getPath();
@@ -746,7 +736,8 @@
return directoryPath + File.separator + temporaryFileName;
}
- private void removePrefixFromRelatedMetsAnchorFileFor(String temporaryMetadataFilename) {
+ private void removePrefixFromRelatedMetsAnchorFileFor(String temporaryMetadataFilename)
+ throws IOException {
File temporaryFile = new File(temporaryMetadataFilename);
File temporaryAnchorFile;
@@ -761,7 +752,7 @@
temporaryAnchorFileName = directoryPath + File.separator + temporaryAnchorFileName;
anchorFileName = directoryPath + File.separator + anchorFileName;
- renameMetadataFile(temporaryAnchorFileName, anchorFileName);
+ FilesystemHelper.renameFile(temporaryAnchorFileName, anchorFileName);
}
}
@@ -793,7 +784,7 @@
writeResult = ff.write(temporaryMetadataFileName);
if (writeResult) {
createBackupFile();
- renameMetadataFile(temporaryMetadataFileName, metadataFileName);
+ FilesystemHelper.renameFile(temporaryMetadataFileName, metadataFileName);
removePrefixFromRelatedMetsAnchorFileFor(temporaryMetadataFileName);
}
}
=== added file 'src/de/sub/goobi/helper/FilesystemHelper.java'
--- src/de/sub/goobi/helper/FilesystemHelper.java 1970-01-01 00:00:00 +0000
+++ src/de/sub/goobi/helper/FilesystemHelper.java 2012-05-09 13:36:18 +0000
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the Goobi Application - a Workflow tool for the support of
+ * mass digitization.
+ *
+ * Visit the websites for more information.
+ * - http://gdz.sub.uni-goettingen.de
+ * - http://www.goobi.org
+ * - http://launchpad.net/goobi-production
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package de.sub.goobi.helper;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.SystemUtils;
+import org.apache.log4j.Logger;
+
+import de.sub.goobi.config.ConfigMain;
+
+/**
+ * Helper class for file system operations.
+ *
+ * @author Matthias Ronge <matthias.ronge@xxxxxxxxxxxx>
+ */
+public class FilesystemHelper {
+ private static final Logger logger = Logger
+ .getLogger(FilesystemHelper.class);
+
+ /**
+ * This function implements file renaming. Renaming of files is full of
+ * mischief under Windows which unaccountably holds locks on files.
+ * Sometimes running the JVM’s garbage collector puts things right.
+ *
+ * @param oldFileName
+ * File to move or rename
+ * @param newFileName
+ * New file name / destination
+ * @throws IOException
+ * is thrown if the rename fails permanently
+ */
+ public static void renameFile(String oldFileName, String newFileName)
+ throws IOException {
+ final int SLEEP_INTERVAL_MILLIS = 20;
+ final int MAX_WAIT_MILLIS = 150000; // 2½ minutes
+ File oldFile;
+ File newFile;
+ boolean success;
+ int millisWaited = 0;
+
+ if (oldFileName != null && newFileName != null) {
+ oldFile = new File(oldFileName);
+ newFile = new File(newFileName);
+ do {
+ if (SystemUtils.IS_OS_WINDOWS
+ && millisWaited == SLEEP_INTERVAL_MILLIS) {
+ logger.warn("renameMetadataFile(): This is Windows. Running the garbage collector may yield good results. Forcing immediate garbage collection now!");
+ System.gc();
+ }
+ success = oldFile.renameTo(newFile);
+ if (!success) {
+ if (millisWaited == 0)
+ logger.info("renameMetadataFile(): Rename failed. File may be locked. Retrying.");
+ try {
+ Thread.sleep(SLEEP_INTERVAL_MILLIS);
+ } catch (InterruptedException e) {
+ }
+ millisWaited += SLEEP_INTERVAL_MILLIS;
+ }
+ } while (!success && millisWaited < MAX_WAIT_MILLIS);
+ if (!success) {
+ logger.error("renameMetadataFile(): Rename failed. This is a permanent error. Giving up.");
+ throw new IOException("Renaming of " + oldFileName + " into "
+ + newFileName + " failed.");
+ } else if (millisWaited > 0)
+ logger.info("renameMetadataFile(): Rename finally succeeded after"
+ + Integer.toString(millisWaited) + " milliseconds.");
+ }
+ }
+}
Follow ups