diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/locking/NioFileLocker.java b/spring-integration-file/src/main/java/org/springframework/integration/file/locking/NioFileLocker.java
index 78cf260dba..d427ca6919 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/locking/NioFileLocker.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/locking/NioFileLocker.java
@@ -16,15 +16,15 @@
package org.springframework.integration.file.locking;
-import org.springframework.messaging.MessagingException;
-import org.springframework.integration.file.FileReadingMessageSource;
-
import java.io.File;
import java.io.IOException;
import java.nio.channels.FileLock;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import org.springframework.integration.file.FileReadingMessageSource;
+import org.springframework.messaging.MessagingException;
+
/**
* File locking strategy that uses java.nio. The locks taken by FileChannel are shared with all the threads in a single
* JVM, so this locking strategy does not prevent files being picked up multiple times within the same JVM.
@@ -39,45 +39,46 @@ import java.util.concurrent.ConcurrentMap;
*/
public class NioFileLocker extends AbstractFileLockerFilter {
- private final ConcurrentMap lockCache = new ConcurrentHashMap();
+ private final ConcurrentMap lockCache = new ConcurrentHashMap();
- /**
- * {@inheritDoc}
- */
- public boolean lock(File fileToLock) {
- FileLock lock = this.lockCache.get(fileToLock);
- if (lock == null) {
- FileLock newLock = null;
- try {
- newLock = FileChannelCache.tryLockFor(fileToLock);
- }
-catch (IOException e) {
- throw new MessagingException("Failed to lock file: "
- + fileToLock, e);
- }
- if (newLock != null) {
- FileLock original = this.lockCache.putIfAbsent(fileToLock, newLock);
- lock = original != null ? original : newLock;
- }
- }
- return lock != null;
- }
-
- public boolean isLockable(File file) {
- return this.lockCache.containsKey(file) || !FileChannelCache.isLocked(file);
- }
-
- public void unlock(File fileToUnlock) {
- FileLock fileLock = this.lockCache.get(fileToUnlock);
- try {
- if (fileLock != null) {
- fileLock.release();
- }
- FileChannelCache.closeChannelFor(fileToUnlock);
- }
-catch (IOException e) {
- throw new MessagingException("Failed to unlock file: "
- + fileToUnlock, e);
- }
+ /**
+ * {@inheritDoc}
+ */
+ public boolean lock(File fileToLock) {
+ FileLock lock = this.lockCache.get(fileToLock);
+ if (lock == null) {
+ FileLock newLock;
+ try {
+ newLock = FileChannelCache.tryLockFor(fileToLock);
+ }
+ catch (IOException e) {
+ throw new MessagingException("Failed to lock file: "
+ + fileToLock, e);
+ }
+ if (newLock != null) {
+ FileLock original = this.lockCache.putIfAbsent(fileToLock, newLock);
+ lock = original != null ? original : newLock;
+ }
+ }
+ return lock != null;
}
+
+ public boolean isLockable(File file) {
+ return this.lockCache.containsKey(file) || !FileChannelCache.isLocked(file);
+ }
+
+ @Override
+ public void unlock(File fileToUnlock) {
+ FileLock fileLock = this.lockCache.remove(fileToUnlock);
+ try {
+ if (fileLock != null) {
+ fileLock.release();
+ }
+ FileChannelCache.closeChannelFor(fileToUnlock);
+ }
+ catch (IOException e) {
+ throw new MessagingException("Failed to unlock file: " + fileToUnlock, e);
+ }
+ }
+
}
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 10e4c97f9d..cd9bd4cfa7 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
@@ -18,20 +18,24 @@ package org.springframework.integration.file.locking;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
+import java.lang.reflect.Field;
import java.util.ArrayList;
-import java.util.List;
+import java.util.Map;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.springframework.integration.file.filters.FileListFilter;
+import org.springframework.integration.test.util.TestUtils;
/**
* @author Iwein Fuld
+ * @author Gary Russell
*/
public class NioFileLockerTests {
@@ -46,25 +50,31 @@ public class NioFileLockerTests {
}
};
- @Test
- public void fileListedByFirstFilter() throws IOException {
- NioFileLocker filter = new NioFileLocker();
- File testFile = new File(workdir, "test0");
- testFile.createNewFile();
- assertThat(filter.filterFiles(workdir.listFiles()).get(0), is(testFile));
- filter.lock(testFile);
- assertThat(filter.filterFiles(workdir.listFiles()).get(0), is(testFile));
- }
+ @Test
+ public void fileListedByFirstFilter() throws Exception {
+ NioFileLocker filter = new NioFileLocker();
+ File testFile = new File(workdir, "test0");
+ testFile.createNewFile();
+ assertThat(filter.filterFiles(workdir.listFiles()).get(0), is(testFile));
+ filter.lock(testFile);
+ assertThat(filter.filterFiles(workdir.listFiles()).get(0), is(testFile));
+ filter.unlock(testFile);
+ Field channelCache = FileChannelCache.class.getDeclaredField("channelCache");
+ channelCache.setAccessible(true);
+ assertTrue(((Map, ?>) channelCache.get(null)).isEmpty());
+ assertTrue(TestUtils.getPropertyValue(filter, "lockCache", Map.class).isEmpty());
+ }
- @Test
- public void fileNotListedWhenLockedByOtherFilter() throws IOException {
- NioFileLocker filter1 = new NioFileLocker();
- FileListFilter filter2 = new NioFileLocker();
- File testFile = new File(workdir, "test1");
- testFile.createNewFile();
- assertThat(filter1.filterFiles(workdir.listFiles()).get(0), is(testFile));
- filter1.lock(testFile);
- assertThat(filter2.filterFiles(workdir.listFiles()), is((List) new ArrayList()));
- }
+ @Test
+ public void fileNotListedWhenLockedByOtherFilter() throws IOException {
+ NioFileLocker filter1 = new NioFileLocker();
+ FileListFilter filter2 = new NioFileLocker();
+ File testFile = new File(workdir, "test1");
+ testFile.createNewFile();
+ assertThat(filter1.filterFiles(workdir.listFiles()).get(0), is(testFile));
+ filter1.lock(testFile);
+ assertThat(filter2.filterFiles(workdir.listFiles()), is(new ArrayList()));
+ filter1.unlock(testFile);
+ }
}