[ https://issues.apache.org/jira/browse/TRANSACTION-19?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12505411 ]
Bojan Vukojevic commented on TRANSACTION-19: -------------------------------------------- Here is the use case: 1. Login in to Linux/Unix box 2. Create a file (i.e. touch /tmp/testFile) 3. Create a symlink in the same directory to this file (i.e. ln -s /tmp/testFile /tmp/testFileLink) * at the end you should see something like: ls -l /tmp/testFile* -rw-r--r-- 1 bvukojev --- 0 Jun 15 15:58 /tmp/testFile lrwxrwxrwx 1 bvukojev ---- 13 Jun 15 15:58 /tmp/testFileLink -> /tmp/testFile 4. Then write a simple test program that should first delete the file then the link; something like: public static void main(String[] args) { final Log log = LogFactory.getLog(TestJakartaCommons.class.getName()); final LoggerFacade sLogger = new CommonsLoggingLogger(log); // validate setup is right: if (new File("/tmp/testFileLink").exists() && (new File("/tmp/testFile").exists())) { FileResourceManager frm = new FileResourceManager("/tmp", "work", false, sLogger); String txId = null; try { frm.start(); txId = frm.generatedUniqueTxId(); frm.startTransaction(txId); frm.deleteResource(txId, "testFile"); frm.deleteResource(txId, "testFileLink"); frm.commitTransaction(txId); } catch (ResourceManagerSystemException e) { // TODO Auto-generated catch block e.printStackTrace(); try { frm.rollbackTransaction(txId); } catch (Exception e1) { e1.printStackTrace(); } } catch (ResourceManagerException e) { // TODO Auto-generated catch block e.printStackTrace(); try { frm.rollbackTransaction(txId); } catch (Exception e1) { e1.printStackTrace(); } } try { frm.stop(FileResourceManager.SHUTDOWN_MODE_NORMAL); } catch (ResourceManagerSystemException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 5. Run the program: Jun 15, 2007 4:21:25 PM org.apache.commons.transaction.util.CommonsLoggingLogger logInfo INFO: Starting RM at '/tmp' / 'work' Jun 15, 2007 4:21:25 PM org.apache.commons.transaction.util.CommonsLoggingLogger logInfo INFO: Started RM Jun 15, 2007 4:21:25 PM org.apache.commons.transaction.util.CommonsLoggingLogger logInfo INFO: Stopping RM at '/tmp' / 'work' Jun 15, 2007 4:21:25 PM org.apache.commons.transaction.util.CommonsLoggingLogger logInfo INFO: Stopped RM 6. All was good! No exceptions! Check the file system that both the file and the link is gone: ls -l /tmp/test* lrwxrwxrwx 1 bvukojev ----- 13 Jun 15 15:58 /tmp/testFileLink -> /tmp/testFile 7. SURPRISE :) Link is still there, only now it is dangling! The issue in in the code below in the applyDeletes method: if (targetFile.exists()) { if (!targetFile.delete()) { throw new IOException("Could not delete file " + removeFile.getName() + " in directory targetDir"); } } After the file is deleted, Java will return "false" for "targetFile.exists()" when target file is a link that is dangling. So the suggested solution is to modify the above code as follows: if (targetFile.exists()) { if (!targetFile.delete()) { throw new IOException("Could not delete file " + removeFile.getName() + " in directory targetDir"); } } else if(!targetFile.isFile()){ //this is likely a dangling link targetFile.delete(); } Please let me know if any more details is necessary.. I'll be happy to provide more details. I am very pleasantly surprised with the turnaround time... Thx! > applyDeletes method does not delete dangling links > -------------------------------------------------- > > Key: TRANSACTION-19 > URL: https://issues.apache.org/jira/browse/TRANSACTION-19 > Project: Commons Transaction > Issue Type: Bug > Affects Versions: 1.2 > Environment: Linux CentOS, Java 1.5 > Reporter: Bojan Vukojevic > Assignee: Oliver Zeigermann > > applyDeletes method will not delete any dangling links. Even if the link was > valid, code may run into this situation if the file is passed to be deleted > before link is registered for deletion. Code will delete the file > effectivelly creating a dangling link that will not be deleted. > The fix might be another change to applyDeletes method i.e. something like: > protected static void applyDeletes(File removeDir, File targetDir, File > rootDir) throws IOException { > if (removeDir.isDirectory() && targetDir.isDirectory()) { > File[] files = removeDir.listFiles(); > for (int i = 0; i < files.length; i++) { > File removeFile = files[i]; > File targetFile = new File(targetDir, removeFile.getName()); > if (!removeFile.isDirectory()) { > if (targetFile.exists()) { > if (!targetFile.delete()) { > throw new IOException("Could not delete file " + > removeFile.getName() > + " in directory targetDir"); > } > } else if(!targetFile.isFile()){ //============ CHANGE > to delete dangling link============= > //this is likely a dangling link > targetFile.delete(); > } > // indicate, this has been done > removeFile.delete(); > } else { > applyDeletes(removeFile, targetFile, rootDir); > } > // delete empty target directories, except root dir > if (!targetDir.equals(rootDir) && targetDir.list().length == > 0) { > targetDir.delete(); > } > } > } > } -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]