Lucene - Core
  1. Lucene - Core
  2. LUCENE-4165

HunspellDictionary - AffixFile Reader closed, Dictionary Readers left unclosed

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 3.6
    • Fix Version/s: 3.6.1, 4.0-BETA, 6.0
    • Component/s: modules/analysis
    • Labels:
      None
    • Environment:

      Linux, Java 1.6

    • Lucene Fields:
      New

      Description

      The HunspellDictionary takes an InputStream for affix file and a List of Streams for dictionaries.

      Javadoc is not clear about i have to close those stream myself or the Dictionary constructor does this already.

      Looking at the code, at least reader.close() is called when the affix file is read via readAffixFile() method (although closing streams is not done in a finally block - so the constructor may fail to do so).
      The readDictionaryFile() method does miss the call to close the reader in contrast to readAffixFile().

      So the question here is - have i have to close the streams myself after instantiating the dictionary?
      Or is the close call only missing for the dictionary streams?
      Either way, please add the close calls in a safe manner or clarify javadoc so i have to do this myself.

      1. lucene_36.patch
        6 kB
        Torsten Krah
      2. LUCENE_4156_36.patch
        8 kB
        Torsten Krah
      3. lucene_trunk.patch
        8 kB
        Torsten Krah
      4. LUCENE-4156-trunk.patch
        10 kB
        Chris Male

        Activity

        Hide
        Chris Male added a comment - - edited

        You're right, we should clean up the Streams and make it clear. Do you want to put together a patch which addresses this?

        Show
        Chris Male added a comment - - edited You're right, we should clean up the Streams and make it clear. Do you want to put together a patch which addresses this?
        Hide
        Torsten Krah added a comment -

        Yeah i can do so. Against trunk only or branch-3.6 too?

        Show
        Torsten Krah added a comment - Yeah i can do so. Against trunk only or branch-3.6 too?
        Hide
        Chris Male added a comment -

        Trunk and 3.6 would be fantastic since this is really a bug fix so we'll get it into 3.6.1.

        Show
        Chris Male added a comment - Trunk and 3.6 would be fantastic since this is really a bug fix so we'll get it into 3.6.1.
        Hide
        Torsten Krah added a comment -
        • Patch against trunk and 3.6.
        • Resources are closed asap.
        • Finally block in constructor added to be sure resources are closed too if an exception is hit before resources are processed.
        • Test modified to check if close() was called on the provided streams after the Dictionary constructor was called.
        Show
        Torsten Krah added a comment - Patch against trunk and 3.6. Resources are closed asap. Finally block in constructor added to be sure resources are closed too if an exception is hit before resources are processed. Test modified to check if close() was called on the provided streams after the Dictionary constructor was called.
        Hide
        Chris Male added a comment -

        Isn't it sufficient to have the streams closed in the finally block of the constructor? Is there any reason we need to close them in readAffix and readDictionary as well?

        Show
        Chris Male added a comment - Isn't it sufficient to have the streams closed in the finally block of the constructor? Is there any reason we need to close them in readAffix and readDictionary as well?
        Hide
        Torsten Krah added a comment - - edited

        It would should be sufficient.
        Only reason i did was, that fd is freed asap it is not needed anymore to get rid of it, just in case processing of the others may take time.
        But its a more theoretical scenario, because file descriptors should not be that "low" to make a real world difference here.
        Should i'll provide new patches?

        Obsoleted comment, see next one from me.

        Show
        Torsten Krah added a comment - - edited It would should be sufficient. Only reason i did was, that fd is freed asap it is not needed anymore to get rid of it, just in case processing of the others may take time. But its a more theoretical scenario, because file descriptors should not be that "low" to make a real world difference here. Should i'll provide new patches? Obsoleted comment, see next one from me.
        Hide
        Chris Male added a comment -

        That'd be great if you could since I think it is cleaner for them to be closed in one place.

        Show
        Chris Male added a comment - That'd be great if you could since I think it is cleaner for them to be closed in one place.
        Hide
        Torsten Krah added a comment - - edited

        Just did think about it again and would prefer to close the readers explicitly too.
        A Reader may internally acquire other resources (byte buffers etc.) which must/should be released too (e.g. have a look at: com.sun.org.apache.xerces.internal.impl.io.UTF8Reader).
        Calling close() on the reader should imho be done too - do you agree with me?

        Show
        Torsten Krah added a comment - - edited Just did think about it again and would prefer to close the readers explicitly too. A Reader may internally acquire other resources (byte buffers etc.) which must/should be released too (e.g. have a look at: com.sun.org.apache.xerces.internal.impl.io.UTF8Reader). Calling close() on the reader should imho be done too - do you agree with me?
        Hide
        Chris Male added a comment -

        Yes you're quite right actually. Okay we'll go with closing them in both places.

        Show
        Chris Male added a comment - Yes you're quite right actually. Okay we'll go with closing them in both places.
        Hide
        Uwe Schindler added a comment -

        Two things:

        • In Lucene we have a variant of the Java 7 close with resources logic. It is (including examples) in the utility package (IOUtils). We should use this, as it correctly handles special cases like supressing Exceptions occuring on close(). It also ensures, all resources are closed.
        • from my perspective / in my opinion: the general contract in Java is, that methods getting streams or readers don't close. This is e.g. important if you have the stuff in a ZIP file and read it with ZIPInputStream. If you close that reader, you cannot read the other files in the archive anymore. So I would prefer to let the user close the files. Behavior in APIs is different for methods taking file names, of course. They close their internal streams. We also fixed other places in Lucene to respect this contract. E.g., IndexWriter does not close readers from Field instances.
        Show
        Uwe Schindler added a comment - Two things: In Lucene we have a variant of the Java 7 close with resources logic. It is (including examples) in the utility package (IOUtils). We should use this, as it correctly handles special cases like supressing Exceptions occuring on close(). It also ensures, all resources are closed. from my perspective / in my opinion: the general contract in Java is, that methods getting streams or readers don't close. This is e.g. important if you have the stuff in a ZIP file and read it with ZIPInputStream. If you close that reader, you cannot read the other files in the archive anymore. So I would prefer to let the user close the files. Behavior in APIs is different for methods taking file names, of course. They close their internal streams. We also fixed other places in Lucene to respect this contract. E.g., IndexWriter does not close readers from Field instances.
        Hide
        Chris Male added a comment -

        So we should close any Readers we internally create (such as in readDictionaryFile()) but leave the InputStreams that have been passed in?

        Show
        Chris Male added a comment - So we should close any Readers we internally create (such as in readDictionaryFile()) but leave the InputStreams that have been passed in?
        Hide
        Uwe Schindler added a comment -

        If you close the Reader it automatically closes all underlying streams (see docs). So: No, you simply wrap any readers around in your code and let GC do its work. Reader dont allocate any resources like file handles whatever. InputStreamReader just wraps a CharsetDecoder on top. Buffers it allocates will be freed by GC.

        So just take the IS as got from caller, do something with it (e.g. wrap a Reader on top) and then return method without doing anything. Closing any wrapped readers would break the contract. If the caller closes the InputStream he releases resources.

        Show
        Uwe Schindler added a comment - If you close the Reader it automatically closes all underlying streams (see docs). So: No, you simply wrap any readers around in your code and let GC do its work. Reader dont allocate any resources like file handles whatever. InputStreamReader just wraps a CharsetDecoder on top. Buffers it allocates will be freed by GC. So just take the IS as got from caller, do something with it (e.g. wrap a Reader on top) and then return method without doing anything. Closing any wrapped readers would break the contract. If the caller closes the InputStream he releases resources.
        Hide
        Chris Male added a comment -

        Okay, makes sense. Then we need to pull out the close in readAffixFile and document that we don't close anything (even if it is the general Java contract, will still be helpful for users to know).

        Show
        Chris Male added a comment - Okay, makes sense. Then we need to pull out the close in readAffixFile and document that we don't close anything (even if it is the general Java contract, will still be helpful for users to know).
        Hide
        Uwe Schindler added a comment -

        We should document it, that would be good.

        The example with the ZIPInputStream is the number one example, why a method should not close streams passed to it Otherwise you need horrible things like "CloseShieldInputStream" (as used by TIKA) to prevent closing for the ZIP file case.

        Show
        Uwe Schindler added a comment - We should document it, that would be good. The example with the ZIPInputStream is the number one example, why a method should not close streams passed to it Otherwise you need horrible things like "CloseShieldInputStream" (as used by TIKA) to prevent closing for the ZIP file case.
        Hide
        Torsten Krah added a comment - - edited

        Just my 2 cents:

        But GC may or may not happend and you will run out of file descriptors sooner or later. You can't rely on GC to kick in and clean up and the resources may be gone already (fd run out e.g.).

        ZIPInputstream is a good example, the Inflater instance there does use non heap memory and is only freed if "inflater.end()" is called. This will be done via finalize - but you are going to see OOMException before, because you may have enough heap and GC decides not to collect your ZIS instance, but the memory used by the inflater is full.

        And creating Readers and not closing them is imho not good either, e.g. take a look at: com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.
        No finalize there, if you do not call close on that reader, the ThreadLocal allocated does leak - imho if you create readers, you should close them.

        In this case the readers are not allocating extra stuff so closing the streams can be done by the user, but imho not closing internally created readers is not good. Than to not take InputStreams as arguments but use a Reader and document that the callee must call close on that reader.

        Show
        Torsten Krah added a comment - - edited Just my 2 cents: But GC may or may not happend and you will run out of file descriptors sooner or later. You can't rely on GC to kick in and clean up and the resources may be gone already (fd run out e.g.). ZIPInputstream is a good example, the Inflater instance there does use non heap memory and is only freed if "inflater.end()" is called. This will be done via finalize - but you are going to see OOMException before, because you may have enough heap and GC decides not to collect your ZIS instance, but the memory used by the inflater is full. And creating Readers and not closing them is imho not good either, e.g. take a look at: com.sun.org.apache.xerces.internal.impl.io.UTF8Reader. No finalize there, if you do not call close on that reader, the ThreadLocal allocated does leak - imho if you create readers, you should close them. In this case the readers are not allocating extra stuff so closing the streams can be done by the user, but imho not closing internally created readers is not good. Than to not take InputStreams as arguments but use a Reader and document that the callee must call close on that reader.
        Hide
        Robert Muir added a comment -

        Than to not take InputStreams as arguments but use a Reader and document that the callee must call close on that reader.

        I think the challenge is the caller does not know how to supply a reader as the encoding is specified in the .aff file.

        Show
        Robert Muir added a comment - Than to not take InputStreams as arguments but use a Reader and document that the callee must call close on that reader. I think the challenge is the caller does not know how to supply a reader as the encoding is specified in the .aff file.
        Hide
        Torsten Krah added a comment - - edited

        Hm thats correct - but than the Reader should imho be closed anyway and the callee must be aware (via docs) that in any failure case, he should cleanup the streams provided or he may leak some fd.

        Show
        Torsten Krah added a comment - - edited Hm thats correct - but than the Reader should imho be closed anyway and the callee must be aware (via docs) that in any failure case, he should cleanup the streams provided or he may leak some fd.
        Hide
        Chris Male added a comment -

        Did you actually run into any problems (lack of fds, OOMs) Torsten? or was it just the lack of documentation that made you aware of the issue?

        Show
        Chris Male added a comment - Did you actually run into any problems (lack of fds, OOMs) Torsten? or was it just the lack of documentation that made you aware of the issue?
        Hide
        Torsten Krah added a comment -

        Not yet.
        It was a pure lack of documentation and as Tika got leaking descriptors in v0.9 which really hurt me, i thought it might be a good idea to find a solution .

        I am using a custom Tokenizer and wanted to use the HunspellDictionary and did not know if i have to close the streams or not because docs does not tell.
        Looking at the code it does close the affix reader, but does not close the dicionary ones - so here is at least a gap .

        Using "lsof" you can see the affic file descriptor vanishing and the dictionary one still there (because i did not close the stream), so it does leak yet.

        Show
        Torsten Krah added a comment - Not yet. It was a pure lack of documentation and as Tika got leaking descriptors in v0.9 which really hurt me, i thought it might be a good idea to find a solution . I am using a custom Tokenizer and wanted to use the HunspellDictionary and did not know if i have to close the streams or not because docs does not tell. Looking at the code it does close the affix reader, but does not close the dicionary ones - so here is at least a gap . Using "lsof" you can see the affic file descriptor vanishing and the dictionary one still there (because i did not close the stream), so it does leak yet.
        Hide
        Chris Male added a comment -

        Okay then I think a reasonable solution would be to remove the close from readAffixFile and document then it is the callers responsibility to close the Streams.

        Show
        Chris Male added a comment - Okay then I think a reasonable solution would be to remove the close from readAffixFile and document then it is the callers responsibility to close the Streams.
        Hide
        Uwe Schindler added a comment -

        And creating Readers and not closing them is imho not good either, e.g. take a look at: com.sun.org.apache.xerces.internal.impl.io.UTF8Reader. No finalize there, if you do not call close on that reader, the ThreadLocal allocated does leak - imho if you create readers, you should close them.

        LOOOOL UTF8Reader of Xerces is broken, so don't take this one as example. It should go away, especially it is slower (like Jettys broken readers, too) than recent Java ones. In times of Java 1.1 there was a speed improvement, but not any more.

        The Readers we wrap around the InputStream are standard Java readers (InputStreamReader) and we really don't need to close them. This is done everywhere that way. BufferedReader (if needed), also needs no close. No broken ThreadLocals, nothing, just plain GC. So please don't do any crazy stuff here.

        The only thing that takes system resources like FDs may be the InputStream from a File or ZIP file. And those will be closed by the caller.

        We should just document that the InputStream is not closed. There is nothing to worry about. We had a similar discussion already in the past with the Readers passed to Fields.

        Uwe

        Show
        Uwe Schindler added a comment - And creating Readers and not closing them is imho not good either, e.g. take a look at: com.sun.org.apache.xerces.internal.impl.io.UTF8Reader. No finalize there, if you do not call close on that reader, the ThreadLocal allocated does leak - imho if you create readers, you should close them. LOOOOL UTF8Reader of Xerces is broken, so don't take this one as example. It should go away, especially it is slower (like Jettys broken readers, too) than recent Java ones. In times of Java 1.1 there was a speed improvement, but not any more. The Readers we wrap around the InputStream are standard Java readers (InputStreamReader) and we really don't need to close them. This is done everywhere that way. BufferedReader (if needed), also needs no close. No broken ThreadLocals, nothing, just plain GC. So please don't do any crazy stuff here. The only thing that takes system resources like FDs may be the InputStream from a File or ZIP file. And those will be closed by the caller. We should just document that the InputStream is not closed. There is nothing to worry about. We had a similar discussion already in the past with the Readers passed to Fields. Uwe
        Hide
        Torsten Krah added a comment - - edited

        I did not say its a good example, but its a example that match the docs.
        A reader may allocate resources depending on the implementation and you are creating and not closing them - you may leak resources a reader may have allocated - that was the purpose for that example; you can imagine every reader you want (e.g. a Buffered one which does buffer things on disk and clear the files if you call close ...).

        The actual JRE implementation used does not use such readers - but imho you should not depend on implementation when using an interface; the JRE implementation may change and code will leak resources in that case.
        Why should a reader have a close() method if you should not call it when you are done? And relying on GC is never a good idea when it comes to resources and you actually do not know what system resources are acquired by the readers, because you can't know what implementation is used and because of that, you don't even know for sure if "finalize" does call close.

        Whats the problem with calling close on that readers and tell the caller that the stream is consumed and closed?

        You said: "This is done everywhere that way." - hm what do you mean with everywhere? Usually at least i do close all my readers which i did create.

        At least it should be made clear, which was the purpose of the report, whatever solution is accepted - close the readers or do not close them and tell the caller to close the input streams.

        Show
        Torsten Krah added a comment - - edited I did not say its a good example, but its a example that match the docs. A reader may allocate resources depending on the implementation and you are creating and not closing them - you may leak resources a reader may have allocated - that was the purpose for that example; you can imagine every reader you want (e.g. a Buffered one which does buffer things on disk and clear the files if you call close ...). The actual JRE implementation used does not use such readers - but imho you should not depend on implementation when using an interface; the JRE implementation may change and code will leak resources in that case. Why should a reader have a close() method if you should not call it when you are done? And relying on GC is never a good idea when it comes to resources and you actually do not know what system resources are acquired by the readers, because you can't know what implementation is used and because of that, you don't even know for sure if "finalize" does call close. Whats the problem with calling close on that readers and tell the caller that the stream is consumed and closed? You said: "This is done everywhere that way." - hm what do you mean with everywhere? Usually at least i do close all my readers which i did create. At least it should be made clear, which was the purpose of the report, whatever solution is accepted - close the readers or do not close them and tell the caller to close the input streams.
        Hide
        Uwe Schindler added a comment - - edited

        -1, don't close InputStreams. We do this nowhere in Lucene (of course we close streams, but only if we open them. Wrapping is not opening, it's just decorating the underlying).

        You said: "This is done everywhere that way." - hm what do you mean with everywhere? Usually at least i do close all my readers which i did create.

        I am talking about libraries. Of course the end user code closes the underlying stream. And with the filter-reader contract you are wrong. Reader's and InputStream are a Decorator-Pattern API. The close() call of the wrapper just delegates down, but there is no must to call it.

        Whats the problem with calling close on that readers and tell the caller that the stream is consumed and closed?

        See my example with ZIPInputStream. If you close the Reader on top, it will close the ZIPInputStream. You have no chance to read the next ZIP-file entry. There are more examples like this.

        The design of the Lucene TokenStream API also follows the decorator pattern, the same applies for this one.

        Show
        Uwe Schindler added a comment - - edited -1, don't close InputStreams. We do this nowhere in Lucene (of course we close streams, but only if we open them. Wrapping is not opening, it's just decorating the underlying). You said: "This is done everywhere that way." - hm what do you mean with everywhere? Usually at least i do close all my readers which i did create. I am talking about libraries. Of course the end user code closes the underlying stream. And with the filter-reader contract you are wrong. Reader's and InputStream are a Decorator-Pattern API. The close() call of the wrapper just delegates down, but there is no must to call it. Whats the problem with calling close on that readers and tell the caller that the stream is consumed and closed? See my example with ZIPInputStream. If you close the Reader on top, it will close the ZIPInputStream. You have no chance to read the next ZIP-file entry. There are more examples like this. The design of the Lucene TokenStream API also follows the decorator pattern, the same applies for this one.
        Hide
        Torsten Krah added a comment - - edited

        I know the ZIPInputStream problem, but the solution here is, to use a Reader, which does not delegate the close call to the stream, but releases all resources which it did create itself; as you said:

        ... The close() call of the wrapper just delegates down, but there is no must to call it. ...

        So in general not calling close() on readers, may leak resources if they did acquire extra ones beside the stream they take (which is up to the actual implementation used) - so in general its good to close them; there are actual some implementations of cause, which are a PITA to use if you actually call "close" (e.g. the ZIPInputStream problem)- but thats another problem.

        Ok back to topic :-D:

        I am going to add a patch for trunk and branch which does remove the reader.close() call and add a javadoc comment to the constructors, that the streams provided MUST be closed by the caller, right?

        Show
        Torsten Krah added a comment - - edited I know the ZIPInputStream problem, but the solution here is, to use a Reader, which does not delegate the close call to the stream, but releases all resources which it did create itself; as you said: ... The close() call of the wrapper just delegates down, but there is no must to call it. ... So in general not calling close() on readers, may leak resources if they did acquire extra ones beside the stream they take (which is up to the actual implementation used) - so in general its good to close them; there are actual some implementations of cause, which are a PITA to use if you actually call "close" (e.g. the ZIPInputStream problem)- but thats another problem. Ok back to topic :-D: I am going to add a patch for trunk and branch which does remove the reader.close() call and add a javadoc comment to the constructors, that the streams provided MUST be closed by the caller, right?
        Hide
        Uwe Schindler added a comment -

        +1, Yes.

        Show
        Uwe Schindler added a comment - +1, Yes.
        Hide
        Chris Male added a comment -

        +1

        Show
        Chris Male added a comment - +1
        Hide
        Uwe Schindler added a comment -

        to use a Reader, which does not delegate the close call to the stream

        Java Readers do this. The only workaround is e.g. TIKA's CloseShieldInputStream. If you wrap it between the original stream and your InputStreamReader on top, then you can call close on the InputStreamReader.

        About the misunderstanding: The counterpart for close() is the ctor, and close() closes the "underlying" "opened" resource (this is what the docs says). This resource is the stream and nothing else. If you call close on a decorator (like InputStreamReader, BufferedInputStrea), the close call closes the underlying "opened" resource. It talks about nothing else.

        As I said, XERCES UTF8Reader is already horribly broken, it violates Unicode specs and lots of other stuff + it is horribly slow, so its a bad example. If it allocates ThreadLocals, there is no need / requirement to release them on close(). Close() should only close the underlying resource, not any helpers around.

        Show
        Uwe Schindler added a comment - to use a Reader, which does not delegate the close call to the stream Java Readers do this. The only workaround is e.g. TIKA's CloseShieldInputStream. If you wrap it between the original stream and your InputStreamReader on top, then you can call close on the InputStreamReader. About the misunderstanding: The counterpart for close() is the ctor, and close() closes the "underlying" "opened" resource (this is what the docs says). This resource is the stream and nothing else. If you call close on a decorator (like InputStreamReader, BufferedInputStrea), the close call closes the underlying "opened" resource. It talks about nothing else. As I said, XERCES UTF8Reader is already horribly broken, it violates Unicode specs and lots of other stuff + it is horribly slow, so its a bad example. If it allocates ThreadLocals, there is no need / requirement to release them on close(). Close() should only close the underlying resource, not any helpers around.
        Hide
        Torsten Krah added a comment -

        Last 2 cents about the misunderstanding:

        Doc says: "Closes the stream and releases any system resources associated with it.".

        May be read like this:

        1. "it" may actually mean the stream here -> "Closes the stream and releases any system resources associated with the stream."
        2. "it" just meaning the object (reader) itself -> "Closes the stream and releases any system resources associated with the reader."

        Both is possible (is it?) and to me 2. would be more common, because @ variant 1. you do not know, if "close" on the stream does really release any system resources (this is up to the input streams close method, e.g. take the CloseShieldInputStream.) - so if 1. should be the only one meaning of the docs, they are promising things, which they can't enforce .
        But i guess i have to look at english grammer again (long long ago ...) - maybe this is really clear here how it must be understand - if 1. is the only possible one from a language perspective one, than it should imho read more like this:

        "Does call close on the Stream." - not more, because you do not know if any system resources are freed; this should be documented at the close() method of the actual InputStream documentation used.

        Back to topic: I'll provide those patches asap.

        Show
        Torsten Krah added a comment - Last 2 cents about the misunderstanding: Doc says: "Closes the stream and releases any system resources associated with it.". May be read like this: 1. "it" may actually mean the stream here -> "Closes the stream and releases any system resources associated with the stream." 2. "it" just meaning the object (reader) itself -> "Closes the stream and releases any system resources associated with the reader." Both is possible (is it?) and to me 2. would be more common, because @ variant 1. you do not know, if "close" on the stream does really release any system resources (this is up to the input streams close method, e.g. take the CloseShieldInputStream.) - so if 1. should be the only one meaning of the docs, they are promising things, which they can't enforce . But i guess i have to look at english grammer again (long long ago ...) - maybe this is really clear here how it must be understand - if 1. is the only possible one from a language perspective one, than it should imho read more like this: "Does call close on the Stream." - not more, because you do not know if any system resources are freed; this should be documented at the close() method of the actual InputStream documentation used. Back to topic: I'll provide those patches asap.
        Hide
        Torsten Krah added a comment -

        Updated patches:

        1. removed reader.close() call in readAffixFile() function.
        2. Add comment at ctors and arguments to make clear that caller has to close the streams and that the ctor does not close them.
        3. Test modified to check its actually not closed.
        4. Added 2 close calls on the streams in trunk patch for the Test.

        Show
        Torsten Krah added a comment - Updated patches: 1. removed reader.close() call in readAffixFile() function. 2. Add comment at ctors and arguments to make clear that caller has to close the streams and that the ctor does not close them. 3. Test modified to check its actually not closed. 4. Added 2 close calls on the streams in trunk patch for the Test.
        Hide
        Chris Male added a comment -

        Updated version of trunk patch which closes the InputStreams created in Solr's HunspellStemFilterFactory.

        Show
        Chris Male added a comment - Updated version of trunk patch which closes the InputStreams created in Solr's HunspellStemFilterFactory.
        Hide
        Torsten Krah added a comment -

        Updated patch for 36 branch which does handle StemFactory closing.
        Ported IOUtils change from trunk to branch (IOException removed from throws declaration).

        Show
        Torsten Krah added a comment - Updated patch for 36 branch which does handle StemFactory closing. Ported IOUtils change from trunk to branch (IOException removed from throws declaration).
        Hide
        Chris Male added a comment -

        Thanks for doing that Torsten. Would it be possible to make a version that doesn't change IOUtils but instead just catches the useless Exception? 3.6.1 is just a bug fix so I'd rather not change anything unnecessary.

        Show
        Chris Male added a comment - Thanks for doing that Torsten. Would it be possible to make a version that doesn't change IOUtils but instead just catches the useless Exception? 3.6.1 is just a bug fix so I'd rather not change anything unnecessary.
        Hide
        Torsten Krah added a comment -

        Updated patch, removed IOUtils change, catch useless Exception.

        Show
        Torsten Krah added a comment - Updated patch, removed IOUtils change, catch useless Exception.
        Hide
        Chris Male added a comment -

        3x commit in r1361988

        Show
        Chris Male added a comment - 3x commit in r1361988
        Hide
        Uwe Schindler added a comment -

        Can I resolve this one?

        Show
        Uwe Schindler added a comment - Can I resolve this one?
        Hide
        Chris Male added a comment -

        trunk r1362371
        4x 1362373

        Thanks guys!

        Show
        Chris Male added a comment - trunk r1362371 4x 1362373 Thanks guys!
        Hide
        Uwe Schindler added a comment -

        Bulk close for 3.6.1

        Show
        Uwe Schindler added a comment - Bulk close for 3.6.1

          People

          • Assignee:
            Chris Male
            Reporter:
            Torsten Krah
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development