Handle leak while transforming an XML file ?
Added by NoData Found almost 9 years ago
Hello,
I am working on Windows 7 x64 with Saxon-HE 9.7.0-1
I have a list of XML file that I wish to process using some stylesheet and to that end, I use JAXB and the following Java code:
final TransformerFactory tf = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl", this.getClass().getClassLoader());
tf.setFeature(FeatureKeys.LINE_NUMBERING, true);
final InputStream stream = this.getClass().getResourceAsStream("/stylesheets/mediainfo.xsl");
final URL uri = this.getClass().getResource("/stylesheets");
final Source stylesheet = new StreamSource(stream, uri.toString());
final Transformer transformer = tf.newTransformer(stylesheet);
transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, indent ? "yes" : "no");
for (final Path path : files) {
final StreamSource source = new StreamSource(path.toFile());
final Path tmp = Files.createTempFile(path.getParent(), path.getFileName().toString(), "~");
final Result target = new StreamResult(tmp.toFile());
transformer.transform(source, target);
Files.move(tmp, path, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
}
The move operation fails with the following message "Le processus ne peut pas accéder au fichier car ce fichier est utilisé par un autre processus." (it is French for "File is being used by another person or program").
Upon investigating, I think the error is in method net.sf.saxon.jaxp.TransformerImpl.transform(Source, Result)
FileOutputStream stream;
try {
stream = new FileOutputStream(file);
closeResultAfterUse = true;
} catch (FileNotFoundException e) {
throw new XPathException("Failed to create output file", e);
}
destination = xsltExecutable.getProcessor().newSerializer(stream);
As far as I understood the code, the class Serializer closes its output stream only when it was initialized with a File instance, which is not the case here. So, the method transform invoke destination.close() ... which does nothing in that case.
If I switch to Input/OutputStream in the main loop, the error goes away:
for (final Path path : files) {
final Path tmp = Files.createTempFile(path.getParent(), path.getFileName().toString(), "~");
try (final InputStream is = Files.newInputStream(path);
final OutputStream os = Files.newOutputStream(tmp)) {
transformer.transform(new StreamSource(is), new StreamResult(os));
}
Files.move(tmp, path, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
}
Should I create a bug report instead?
Regards,
Replies (3)
Please register to reply
RE: Handle leak while transforming an XML file ? - Added by NoData Found almost 9 years ago
No problem. Dealing with a try-with-resources is a fine work-around for me.
RE: Handle leak while transforming an XML file ? - Added by O'Neil Delpratt over 8 years ago
We have applied a fix to this in the Serializer class to close the file upon completion. Regression testing done, but not really been tested on all platforms
Please register to reply