Skip to content

Commit f2bd8c4

Browse files
garyrussellartembilan
authored andcommitted
Clear lock cache in NioFileLocker (#2998)
Fixes #2980 # Conflicts: # spring-integration-file/src/test/java/org/springframework/integration/file/locking/NioFileLockerTests.java # Conflicts: # spring-integration-file/src/main/java/org/springframework/integration/file/locking/NioFileLocker.java # spring-integration-file/src/test/java/org/springframework/integration/file/locking/NioFileLockerTests.java
1 parent 9d4aa8b commit f2bd8c4

File tree

2 files changed

+71
-60
lines changed

2 files changed

+71
-60
lines changed

spring-integration-file/src/main/java/org/springframework/integration/file/locking/NioFileLocker.java

+41-40
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@
1616

1717
package org.springframework.integration.file.locking;
1818

19-
import org.springframework.messaging.MessagingException;
20-
import org.springframework.integration.file.FileReadingMessageSource;
21-
2219
import java.io.File;
2320
import java.io.IOException;
2421
import java.nio.channels.FileLock;
2522
import java.util.concurrent.ConcurrentHashMap;
2623
import java.util.concurrent.ConcurrentMap;
2724

25+
import org.springframework.integration.file.FileReadingMessageSource;
26+
import org.springframework.messaging.MessagingException;
27+
2828
/**
2929
* File locking strategy that uses java.nio. The locks taken by FileChannel are shared with all the threads in a single
3030
* JVM, so this locking strategy <b>does not</b> prevent files being picked up multiple times within the same JVM.
@@ -39,45 +39,46 @@
3939
*/
4040
public class NioFileLocker extends AbstractFileLockerFilter {
4141

42-
private final ConcurrentMap<File, FileLock> lockCache = new ConcurrentHashMap<File, FileLock>();
42+
private final ConcurrentMap<File, FileLock> lockCache = new ConcurrentHashMap<File, FileLock>();
4343

44-
/**
45-
* {@inheritDoc}
46-
*/
47-
public boolean lock(File fileToLock) {
48-
FileLock lock = this.lockCache.get(fileToLock);
49-
if (lock == null) {
50-
FileLock newLock = null;
51-
try {
52-
newLock = FileChannelCache.tryLockFor(fileToLock);
53-
}
54-
catch (IOException e) {
55-
throw new MessagingException("Failed to lock file: "
56-
+ fileToLock, e);
57-
}
58-
if (newLock != null) {
59-
FileLock original = this.lockCache.putIfAbsent(fileToLock, newLock);
60-
lock = original != null ? original : newLock;
61-
}
62-
}
63-
return lock != null;
64-
}
44+
/**
45+
* {@inheritDoc}
46+
*/
47+
public boolean lock(File fileToLock) {
48+
FileLock lock = this.lockCache.get(fileToLock);
49+
if (lock == null) {
50+
FileLock newLock;
51+
try {
52+
newLock = FileChannelCache.tryLockFor(fileToLock);
53+
}
54+
catch (IOException e) {
55+
throw new MessagingException("Failed to lock file: "
56+
+ fileToLock, e);
57+
}
58+
if (newLock != null) {
59+
FileLock original = this.lockCache.putIfAbsent(fileToLock, newLock);
60+
lock = original != null ? original : newLock;
61+
}
62+
}
63+
return lock != null;
64+
}
6565

66-
public boolean isLockable(File file) {
67-
return this.lockCache.containsKey(file) || !FileChannelCache.isLocked(file);
68-
}
66+
public boolean isLockable(File file) {
67+
return this.lockCache.containsKey(file) || !FileChannelCache.isLocked(file);
68+
}
6969

70-
public void unlock(File fileToUnlock) {
71-
FileLock fileLock = this.lockCache.get(fileToUnlock);
72-
try {
73-
if (fileLock != null) {
74-
fileLock.release();
75-
}
76-
FileChannelCache.closeChannelFor(fileToUnlock);
77-
}
78-
catch (IOException e) {
79-
throw new MessagingException("Failed to unlock file: "
80-
+ fileToUnlock, e);
81-
}
70+
@Override
71+
public void unlock(File fileToUnlock) {
72+
FileLock fileLock = this.lockCache.remove(fileToUnlock);
73+
try {
74+
if (fileLock != null) {
75+
fileLock.release();
76+
}
77+
FileChannelCache.closeChannelFor(fileToUnlock);
78+
}
79+
catch (IOException e) {
80+
throw new MessagingException("Failed to unlock file: " + fileToUnlock, e);
81+
}
8282
}
83+
8384
}

spring-integration-file/src/test/java/org/springframework/integration/file/locking/NioFileLockerTests.java

+30-20
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,24 @@
1818

1919
import static org.hamcrest.CoreMatchers.is;
2020
import static org.junit.Assert.assertThat;
21+
import static org.junit.Assert.assertTrue;
2122

2223
import java.io.File;
2324
import java.io.IOException;
25+
import java.lang.reflect.Field;
2426
import java.util.ArrayList;
25-
import java.util.List;
27+
import java.util.Map;
2628

2729
import org.junit.Rule;
2830
import org.junit.Test;
2931
import org.junit.rules.TemporaryFolder;
3032

3133
import org.springframework.integration.file.filters.FileListFilter;
34+
import org.springframework.integration.test.util.TestUtils;
3235

3336
/**
3437
* @author Iwein Fuld
38+
* @author Gary Russell
3539
*/
3640
public class NioFileLockerTests {
3741

@@ -46,25 +50,31 @@ public void create() throws IOException {
4650
}
4751
};
4852

49-
@Test
50-
public void fileListedByFirstFilter() throws IOException {
51-
NioFileLocker filter = new NioFileLocker();
52-
File testFile = new File(workdir, "test0");
53-
testFile.createNewFile();
54-
assertThat(filter.filterFiles(workdir.listFiles()).get(0), is(testFile));
55-
filter.lock(testFile);
56-
assertThat(filter.filterFiles(workdir.listFiles()).get(0), is(testFile));
57-
}
53+
@Test
54+
public void fileListedByFirstFilter() throws Exception {
55+
NioFileLocker filter = new NioFileLocker();
56+
File testFile = new File(workdir, "test0");
57+
testFile.createNewFile();
58+
assertThat(filter.filterFiles(workdir.listFiles()).get(0), is(testFile));
59+
filter.lock(testFile);
60+
assertThat(filter.filterFiles(workdir.listFiles()).get(0), is(testFile));
61+
filter.unlock(testFile);
62+
Field channelCache = FileChannelCache.class.getDeclaredField("channelCache");
63+
channelCache.setAccessible(true);
64+
assertTrue(((Map<?, ?>) channelCache.get(null)).isEmpty());
65+
assertTrue(TestUtils.getPropertyValue(filter, "lockCache", Map.class).isEmpty());
66+
}
5867

59-
@Test
60-
public void fileNotListedWhenLockedByOtherFilter() throws IOException {
61-
NioFileLocker filter1 = new NioFileLocker();
62-
FileListFilter<File> filter2 = new NioFileLocker();
63-
File testFile = new File(workdir, "test1");
64-
testFile.createNewFile();
65-
assertThat(filter1.filterFiles(workdir.listFiles()).get(0), is(testFile));
66-
filter1.lock(testFile);
67-
assertThat(filter2.filterFiles(workdir.listFiles()), is((List<File>) new ArrayList<File>()));
68-
}
68+
@Test
69+
public void fileNotListedWhenLockedByOtherFilter() throws IOException {
70+
NioFileLocker filter1 = new NioFileLocker();
71+
FileListFilter<File> filter2 = new NioFileLocker();
72+
File testFile = new File(workdir, "test1");
73+
testFile.createNewFile();
74+
assertThat(filter1.filterFiles(workdir.listFiles()).get(0), is(testFile));
75+
filter1.lock(testFile);
76+
assertThat(filter2.filterFiles(workdir.listFiles()), is(new ArrayList<File>()));
77+
filter1.unlock(testFile);
78+
}
6979

7080
}

0 commit comments

Comments
 (0)