1
votes

I have an issue as exactly described here http://forum.spring.io/forum/spring-projects/integration/116827-file-inbound-channel-adapter-with-nio-locker-and-file-to-string-transformer/page2

In my case, an inbound channel adapter with nio-locker setup feeds into a service activator via channel. The service activator gets an exception saying there's a lock on the file.

From the link above, there was no Jira ticket attached so I don't know if it was resolved or not. I see in the documentation that it says nio-locker being shared, but not sure if that includes fixing the Windows 'feature'

Running Windows 8, java 1.8.0_60, Spring Integration 4.1.5

Exception:

Caused by: java.io.IOException: The process cannot access the file because another process has locked a portion of the file

XML Config is spread across two context files.

First context file:

<file:inbound-channel-adapter id="filesIn" prevent-duplicates="true"     auto-startup="false" auto-create-directory="false" channel="fileInChannel"   filter="headerFilter" directory="${input.directory}">
         <int:poller id="poller" fixed-delay="5000" /> 
         <file:nio-locker/>
 </file:inbound-channel-adapter>

Second context file

<int:channel id="fileInChannel">

</int:channel>

<int:service-activator input-channel="fileInChannel"
output-channel="headerEnricherInput" ref="fileHandler" />

Snippet of the service activator

public Message<File> handleFile(Message<File> inputMessage) {
    File input = inputMessage.getPayload();
    String baseName = FilenameUtils.getBaseName(input.getName());
    String headerFileName = baseName + ".xml";

    File headerFile = new File(FilenameUtils.getFullPath(input
            .getAbsolutePath()), headerFileName);

    String transaction = new String();

    try {
        JAXBContext jc = JAXBContext.newInstance(HeaderFile.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        HeaderFile header = (HeaderFile) unmarshaller.unmarshal(headerFile);
        System.out.println("Transaction " + header.getTransaction());
        transaction = header.getTransaction();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Thanks.

1

1 Answers

0
votes

Please, find my code following the links from that forum post:

public static void readAndLogFile(File lockedFile) throws Exception {
    FileLock fileLock = FileChannelCache.tryLockFor(lockedFile);
    FileChannel fileChannel = fileLock.channel();
    ByteBuffer byteBuffer = ByteBuffer.allocate((int) fileChannel.size());
    fileChannel.read(byteBuffer);
    System.out.println("Read File " + lockedFile.getName() + " from process " + JVM_PROCESS_ID + " with content: " + new String(byteBuffer.array()));
}

As you see we should use FileChannel which is responsible for the lock to read file content.

The Unix is a bit forgiven in case of mutually exclusive file lock. But with Windows we are exactly there :-).