diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/locking/FileChannelCache.java b/spring-integration-file/src/main/java/org/springframework/integration/file/locking/FileChannelCache.java index 781d85e628..ed7a4ad46e 100644 --- a/spring-integration-file/src/main/java/org/springframework/integration/file/locking/FileChannelCache.java +++ b/spring-integration-file/src/main/java/org/springframework/integration/file/locking/FileChannelCache.java @@ -25,11 +25,14 @@ import java.nio.channels.OverlappingFileLockException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import org.springframework.lang.Nullable; + /** * Static cache of FileLocks that can be used to ensure that only a single lock is used inside this ClassLoader. * * @author Iwein Fuld * @author Gary Russell + * @author Emmanuel Roux * @since 2.0 */ final class FileChannelCache { @@ -49,9 +52,10 @@ final class FileChannelCache { *
* Thread safe. */ + @Nullable public static FileLock tryLockFor(File fileToLock) throws IOException { FileChannel channel = channelCache.get(fileToLock); - if (channel == null) { + if (channel == null && fileToLock.exists()) { @SuppressWarnings("resource") FileChannel newChannel = new RandomAccessFile(fileToLock, "rw").getChannel(); FileChannel original = channelCache.putIfAbsent(fileToLock, newChannel); diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/locking/FileChannelCacheTests.java b/spring-integration-file/src/test/java/org/springframework/integration/file/locking/FileChannelCacheTests.java new file mode 100644 index 0000000000..90f9fb23de --- /dev/null +++ b/spring-integration-file/src/test/java/org/springframework/integration/file/locking/FileChannelCacheTests.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration.file.locking; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +/** + * @author Emmanuel Roux + * @since 4.3.22 + */ +public class FileChannelCacheTests { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Test + public void throwsExceptionWhenFileNotExists() throws IOException { + File testFile = new File(temp.getRoot(), "test0"); + assertThat(testFile.exists()).isFalse(); + assertThat(FileChannelCache.tryLockFor(testFile)).isNull(); + assertThat(testFile.exists()).isFalse(); + } + + @Test + public void fileLocked() throws IOException { + File testFile = temp.newFile("test1"); + testFile.createNewFile(); + assertThat(testFile.exists()).isTrue(); + assertThat(FileChannelCache.tryLockFor(testFile)).isNotNull(); + FileChannelCache.closeChannelFor(testFile); + } + +} diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/locking/NioFileLockerTests.java b/spring-integration-file/src/test/java/org/springframework/integration/file/locking/NioFileLockerTests.java index 3918f77aae..22d43e23af 100644 --- a/spring-integration-file/src/test/java/org/springframework/integration/file/locking/NioFileLockerTests.java +++ b/spring-integration-file/src/test/java/org/springframework/integration/file/locking/NioFileLockerTests.java @@ -34,6 +34,7 @@ import org.springframework.integration.test.util.TestUtils; /** * @author Iwein Fuld * @author Gary Russell + * @author Emmanuel Roux */ public class NioFileLockerTests { @@ -76,4 +77,21 @@ public class NioFileLockerTests { filter1.unlock(testFile); } + @Test + public void fileLockedWhenNotAlreadyLockedAndExists() throws IOException { + NioFileLocker locker = new NioFileLocker(); + File testFile = new File(workdir, "test2"); + testFile.createNewFile(); + assertThat(locker.lock(testFile)).isTrue(); + locker.unlock(testFile); + } + + @Test + public void fileNotLockedWhenNotExists() throws IOException { + NioFileLocker locker = new NioFileLocker(); + File testFile = new File(workdir, "test3"); + assertThat(locker.lock(testFile)).isFalse(); + assertThat(testFile.exists()).isFalse(); + } + }