Index: logback-core/src/test/java/ch/qos/logback/core/rolling/helper/PackageTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP <+>/**\n * Logback: the reliable, generic, fast and flexible logging framework.\n * Copyright (C) 1999-2015, QOS.ch. All rights reserved.\n *\n * This program and the accompanying materials are dual-licensed under\n * either the terms of the Eclipse Public License v1.0 as published by\n * the Eclipse Foundation\n *\n * or (per the licensee's choosing)\n *\n * under the terms of the GNU Lesser General Public License version 2.1\n * as published by the Free Software Foundation.\n */\npackage ch.qos.logback.core.rolling.helper;\n\nimport ch.qos.logback.core.util.DatePatternToRegexTest;\nimport junit.framework.TestCase;\n\nimport org.junit.runner.RunWith;\nimport org.junit.runners.Suite;\n\n@RunWith(Suite.class)\n@Suite.SuiteClasses( { CompressTest.class, FileNamePatternTest.class,\n RollingCalendarTest.class, DatePatternToRegexTest.class })\npublic class PackageTest extends TestCase {\n\n}\n Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- logback-core/src/test/java/ch/qos/logback/core/rolling/helper/PackageTest.java (revision eb1f6d79c2a63c9359ff3c268bcaac562c3ba424) +++ logback-core/src/test/java/ch/qos/logback/core/rolling/helper/PackageTest.java (revision ) @@ -21,7 +21,7 @@ @RunWith(Suite.class) @Suite.SuiteClasses( { CompressTest.class, FileNamePatternTest.class, - RollingCalendarTest.class, DatePatternToRegexTest.class }) + RollingCalendarTest.class, DatePatternToRegexTest.class, RenameUtilTest.class }) public class PackageTest extends TestCase { } Index: logback-core/src/main/java/ch/qos/logback/core/rolling/helper/RenameUtil.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP <+>/**\n * Logback: the reliable, generic, fast and flexible logging framework.\n * Copyright (C) 1999-2015, QOS.ch. All rights reserved.\n *\n * This program and the accompanying materials are dual-licensed under\n * either the terms of the Eclipse Public License v1.0 as published by\n * the Eclipse Foundation\n *\n * or (per the licensee's choosing)\n *\n * under the terms of the GNU Lesser General Public License version 2.1\n * as published by the Free Software Foundation.\n */\npackage ch.qos.logback.core.rolling.helper;\n\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\n\nimport ch.qos.logback.core.CoreConstants;\nimport ch.qos.logback.core.rolling.RollingFileAppender;\nimport ch.qos.logback.core.rolling.RolloverFailure;\nimport ch.qos.logback.core.spi.ContextAwareBase;\nimport ch.qos.logback.core.util.EnvUtil;\nimport ch.qos.logback.core.util.FileUtil;\n\n\n/**\n * Utility class to help solving problems encountered while renaming files.\n *\n * @author Ceki Gulcu\n */\npublic class RenameUtil extends ContextAwareBase {\n\n static String RENAMING_ERROR_URL = CoreConstants.CODES_URL + \"#renamingError\";\n\n /**\n * A relatively robust file renaming method which in case of failure due to\n * src and target being on different volumes, falls back onto\n * renaming by copying.\n *\n * @param src\n * @param target\n * @throws RolloverFailure\n */\n public void rename(String src, String target) throws RolloverFailure {\n if (src.equals(target)) {\n addWarn(\"Source and target files are the same [\" + src + \"]. Skipping.\");\n return;\n }\n File srcFile = new File(src);\n\n if (srcFile.exists()) {\n File targetFile = new File(target);\n createMissingTargetDirsIfNecessary(targetFile);\n\n addInfo(\"Renaming file [\" + srcFile + \"] to [\" + targetFile + \"]\");\n\n boolean result = srcFile.renameTo(targetFile);\n\n if (!result) {\n addWarn(\"Failed to rename file [\" + srcFile + \"] as [\" + targetFile + \"].\");\n if (areOnDifferentVolumes(srcFile, targetFile)) {\n addWarn(\"Detected different file systems for source [\" + src + \"] and target [\" + target + \"]. Attempting rename by copying.\");\n renameByCopying(src, target);\n return;\n } else {\n addWarn(\"Please consider leaving the [file] option of \" + RollingFileAppender.class.getSimpleName() + \" empty.\");\n addWarn(\"See also \" + RENAMING_ERROR_URL);\n }\n }\n } else {\n throw new RolloverFailure(\"File [\" + src + \"] does not exist.\");\n }\n }\n\n\n /**\n * Attempts tp determine whether both files are on different volumes. Returns true if we could determine that\n * the files are on different volumes. Returns false otherwise or if an error occurred while doing the check.\n *\n * @param srcFile\n * @param targetFile\n * @return true if on different volumes, false otherwise or if an error occurred\n */\n boolean areOnDifferentVolumes(File srcFile, File targetFile) throws RolloverFailure {\n if (!EnvUtil.isJDK7OrHigher())\n return false;\n\n File parentOfTarget = targetFile.getParentFile();\n\n try {\n boolean onSameFileStore = FileStoreUtil.areOnSameFileStore(srcFile, parentOfTarget);\n return !onSameFileStore;\n } catch (RolloverFailure rf) {\n addWarn(\"Error while checking file store equality\", rf);\n return false;\n }\n }\n\n\n\n\n public void renameByCopying(String src, String target)\n throws RolloverFailure {\n\n FileUtil fileUtil = new FileUtil(getContext());\n fileUtil.copy(src, target);\n\n File srcFile = new File(src);\n if (!srcFile.delete()) {\n addWarn(\"Could not delete \" + src);\n }\n\n }\n\n void createMissingTargetDirsIfNecessary(File toFile) throws RolloverFailure {\n boolean result = FileUtil.createMissingParentDirectories(toFile);\n if (!result) {\n throw new RolloverFailure(\"Failed to create parent directories for [\"\n + toFile.getAbsolutePath() + \"]\");\n }\n }\n\n @Override\n public String toString() {\n return \"c.q.l.co.rolling.helper.RenameUtil\";\n }\n}\n Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- logback-core/src/main/java/ch/qos/logback/core/rolling/helper/RenameUtil.java (revision eb1f6d79c2a63c9359ff3c268bcaac562c3ba424) +++ logback-core/src/main/java/ch/qos/logback/core/rolling/helper/RenameUtil.java (revision ) @@ -14,13 +14,6 @@ package ch.qos.logback.core.rolling.helper; -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; - import ch.qos.logback.core.CoreConstants; import ch.qos.logback.core.rolling.RollingFileAppender; import ch.qos.logback.core.rolling.RolloverFailure; @@ -28,7 +21,9 @@ import ch.qos.logback.core.util.EnvUtil; import ch.qos.logback.core.util.FileUtil; +import java.io.File; + /** * Utility class to help solving problems encountered while renaming files. * @@ -92,6 +87,9 @@ return false; File parentOfTarget = targetFile.getParentFile(); + if(parentOfTarget == null) { + return false; + } try { boolean onSameFileStore = FileStoreUtil.areOnSameFileStore(srcFile, parentOfTarget); Index: logback-core/src/test/java/ch/qos/logback/core/rolling/helper/RenameUtilTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- logback-core/src/test/java/ch/qos/logback/core/rolling/helper/RenameUtilTest.java (revision ) +++ logback-core/src/test/java/ch/qos/logback/core/rolling/helper/RenameUtilTest.java (revision ) @@ -0,0 +1,53 @@ +/** + * Logback: the reliable, generic, fast and flexible logging framework. + * Copyright (C) 1999-2015, QOS.ch. All rights reserved. + * + * This program and the accompanying materials are dual-licensed under + * either the terms of the Eclipse Public License v1.0 as published by + * the Eclipse Foundation + * + * or (per the licensee's choosing) + * + * under the terms of the GNU Lesser General Public License version 2.1 + * as published by the Free Software Foundation. + */ +package ch.qos.logback.core.rolling.helper; + +import ch.qos.logback.core.Context; +import ch.qos.logback.core.ContextBase; +import junit.framework.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class RenameUtilTest { + + private RenameUtil renameUtil; + + @Before + public void setup() { + Context context = new ContextBase(); + renameUtil = new RenameUtil(); + renameUtil.setContext(context); + } + + @Test + public void areOnDifferentVolumesTest() throws IOException { + Path userDir = Paths.get(System.getProperty("user.dir")); + File file1 = userDir.resolve("from.txt").toFile(); + try { + file1.createNewFile(); + File file2 = new File("to.txt"); + Assert.assertFalse(renameUtil.areOnDifferentVolumes(file1, file2)); + } finally { + Files.deleteIfExists(file1.toPath()); + } + } + + +}