This has always been a tricky one because it's difficult to apply the standard policy "Whoever creates a Stream is responsible for closing it". In this case Saxon is going to call the DotNetURIResolver, which in return is going to call the .NET XmlResolver; the XmlResolver is likely to return a (.NET) Stream representing the content of the stylesheet module, which we will wrap in a DotNetInputStream, and then in a JAXP StreamSource. The UseWhenFilter then calls StylesheetModule.loadStylesheetModule(source) which isn't going to close the stream unless the source is an AugmentedSource with the "pleaseCloseAfterUse" property set.
Basically, when a stream is created by a URIResolver, there is no way the URIResolver can close the stream after use. In the StandardURIResolver we therefore avoid creating a stream (it returns a SAXSource whose InputSource contains the URI, which we leave the XML parser to dereference). But the DotNetURIResolver calls the XmlResolver, which returns a System.IO.Stream.
I suspect that in DotNetURIResolver.dereference(), where the code currently does
if (obj instanceof Stream) {
StreamSource source = new StreamSource(new DotNetInputStream((Stream) obj));
source.setSystemId(abs.toString());
return source;
we should be doing something like
if (obj instanceof Stream) {
StreamSource source = new StreamSource(new DotNetInputStream((Stream) obj));
source.setSystemId(abs.toString());
AugmentedSource as = new AugmentedSource(source);
as.setPleaseCloseAfterUse(true);
return as;
because no-one else is going to close the stream if we don't.