I have multiple processes running on different machines which are required to read/write to a shared XML file, for this I am using DOM with Java
and FileLocks
(While I know that a database would be a more effective approach, this is not viable due to project constraints) .
To make changes to the XML file, the relevant process first creates an exclusively locked channel which is used to read the file, it then attempts to reuse the same channel to write the new version before closing the channel; this way the lock is never down. The issue however is that I am getting a java.nio.channels.ClosedChannelException
when attempting to write the result, even though I never explicitly close the channel. I have suspicions that the line of code:
doc = dBuilder.parse(Channels.newInputStream(channel));
closes the channel. If so, how could I force the channel to stay open? My code can be seen below:
[removed code after update]
UPDATE: Placing System.out.println(channel.isOpen())
before and after the suspect line of code confirms that this is where the channel is closed.
UPDATE: Having asked a separate question the code below now prevents the channel from closing during the parse operation. The issue now is that instead of replacing the original xml file, the transformer appends the changed document to the original. In the documentation I cannot find any related options for specifying the output of Transformer.transform
(I have searched Transformer
/Transformer factory
/StreamResult
). Am I missing something? Do I need to somehow clear the channel before writing? Thanks.
UPDATE: Finally solved the append issue by truncating the channel to a size of 0. Thank you @JLRishe for the advice. Have posted the working code as an answer.