This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.
Product Version = NetBeans IDE Dev (Build 200406011800) Operating System = Linux version 2.4.22-1.2115.nptl running on i386 Java; VM; Vendor = 1.4.2_04; Java HotSpot(TM) Client VM 1.4.2_04-b05; Sun Microsystems Inc. Java Home = /usr/local/java/j2sdk1.4.2_04/jre System Locale; Encod. = cs_CZ (nb); ISO-8859-2 Home Dir; Current Dir = /usr/local/home/delphym; /usr/local/forte/forte3/NBdev-last/netbeans/bin ------------------------------------------------------------------------------- I've got a XML file which I wan't to Check and Validate. But Checkin' this file cause StackOVerFlowError :-( (without any stacktrace) I'm attaching my XML file which causing it. BTW: reproduction is not as easy as it seems. First Checking will probably pass, theb you have to perform "Validate XML" and after that again "Check XML". No the SOE occures.
Created attachment 15423 [details] my XML file causing SOE
It's 100% reproducible on every 2nd validation of new created XML document. Exception attached.
Created attachment 16059 [details] java.lang.StackOverflowError
It can be connected with the issue #45643
The loop comes from org.netbeans.core.output2.OutputDocument class - see the second attachement. This is caused by calling the reset() method on org.openide.windows.OutputWriter class. If the reset() action is commented out, the StackOverflowError doesn't occure. The method is called from "InitInputOutput(String name)" method (org.netbeans.modues.xml.core.actions.InputOutputReporter class, xml/core module). It seems that reset() is called correctly from there.
Changing component to core/output.
Endless loop fixed. Checking in src/org/netbeans/core/output2/OutputDocument.java; /cvs/core/output2/src/org/netbeans/core/output2/OutputDocument.java,v <-- OutputDocument.java new revision: 1.3; previous revision: 1.2
*** Issue 46046 has been marked as a duplicate of this issue. ***
The fix solved StackOverflowError but now it behaves strange: - call Check XML => it prints something to output window - call Check XML again => it clear output but prints nothing - call Check XML once more => it prints correct output - and so on in a loop
Here is what the XML module is doing: First run: Call IOProvider.getIO() to get an instance of InputOutput. Call InputOutput.getOut() to write to. This creates an instance of OutputWriter (a stream to write to). Second run: Call InputOutput.reset(). This disposes the instance of OutputWriter it had (all future writes to it will go to /dev/null) Call IOProvider.getIO() - as it should do. This constructs a new InputOutput to write to. But then the XML module keeps trying to write to the old, dead InputOutput, instead of the new one it went so far as to ask for. Safest is to simply call InputOutput.getOut() everywhere - that way you'll always get the right instance (if reset() is not called, the same one will be returned). But even if doing it this way worked in the old output window, it was at the very least a memory leak. There is no way to get a reference to the old OutWriter - it had to be held, and shouldn't have been.
Created attachment 16534 [details] Annotated log file (-J-Dnb.output.log.verbose=true) to show exactly what is going wrong and where
Tim, thanks for a useful and helpful evaluation.
*** Issue 45643 has been marked as a duplicate of this issue. ***
Tim OutputWriter.reset() JavaDoc claims that is just erases written data i.e. API alternative to "Clear All". From your description it seems that there is new semantics more close to closing stream as wanted in issue #45126. XML code wants to reuse single OW.
You can reuse a single output tab. You just can't use a single writer. The thing you want to hold onto (though you don't need to, you can just ask using the same name) is the InputOutput instance, not the writer itself. This should be a simple global search and replace, either to hold InputOutput and call getOut() when you need to write something (in which case you'll always get the right OutputWriter back), or just retain the name you want to use and always call IOProvider.getDefault().getIO("whatever").getOut(). Either will work fine, the latter also reduces the risk of memory leaks. The core problem is that the reset() method is on the wrong interface (do you ever really want to reset *only* the stdOut, but not the stdErr?), but we can't really change that. It's a bit of an ambiguous API.
Tim since the current documentation in IOProvider, InputOutput, and OutputWriter are clearly inadequate after the core/output2 rewrite, I suggest you update the Javadoc of these classes to include detailed hints (<div class="nonnormative">) on how the methods should be used to work nicely with the current OW implementation. If possible, give hints that will not break usage on the old core/output, so that it remains feasible to swap in a different terminal impl.
Tim, I propably did not get it. My best approximation is: /** Set output writer used by this displayer. * Share existing, clear content on reuse. #44187 */ private void initInputOutput (String name) { xmlInputOutput = IOProvider.getDefault().getIO(name, false); xmlInputOutput.setFocusTaken (false); activeOutputWriter = xmlInputOutput.getOut(); // clear previous output try { activeOutputWriter.reset(); activeOutputWriter.close(); } catch (IOException e) { ErrorManager.getDefault().notify(e); } activeOutputWriter = xmlInputOutput.getOut(); } but it ignores first attempt to write anything. All subsequent attempts are OK.
Get rid of the call to close() first - if you're resetting it, you don't need it. You should call close() when you're done writing to the stream. The simplest solution to all of this is to simply never hold a reference to anything. When you want to write, call IOProvider.getInputOutput(name).getOut().println("whatever"); When you want to clear/reset, just call IOProvider.getInputOutput(name).getOut().clear/reset/close/whatever and you shouldn't have any problems. The lookup of the output writer by name is very fast - there is rarely more than 1-2 instances around anyway.
Just to clarify, based on issue 45126: If you're calling reset(), don't call close() - resetting will automatically discard the stream, the data, everything. The problem is not calling close() when something's done writing - so the tab name stays bold (and the memory mapped file you were writing to can't be deleted).
Search and replace did not help. The trick is that I need to call auxiliary print() before reset(). Otherwise it ignores all print()s until next reset(). Please check reset() logic. Workarounded in XML. InputOutputReporter.java new revision: 1.17
As I suggested earlier, delete line 246 of InputOutputReporter (244 can go too): 244: out().write ("Reset"); 245: out().reset(); <-- This disposes the old writer - its resources are cleaned up, and the next call to InputOutput.getOut() will give you a new one to use 246: out().close(); <-- Here you are creating the new writer and immediately telling it it's closed and should send any future writes to /dev/null. Call close() when you are done *writing* output and know you won't write anymore, not when you want to start writing something. Once you close it, it's closed.
Workaround removed. It works as expected even without it if always calling static IOProvider. InputOutputReporter.java new revision: 1.18
Tim it works but I still do not understand your explanation: > 246: out().close(); <-- Here you are creating the new writer and > immediately telling it it's closed and should send any future writes > to /dev/null. Fact: close() was called always. But only for the very first invocation after creating new InputOutput it behaves as you describe. On subsequent invocations it feels like it disposes the old writer - its resources are cleaned up, and the next call to InputOutput.getOut() will give me a new one to use. This anomaly was somehow workarounded by out().println();out().reset();out().close() sequence. Then next call to out() i.e. InputOutput.getOut() always return new writer instance.
Finally, there is confusing reset() logic. Why does it destroy the stream? It should rewind it - erase previous output but keep it opened. Convetionally close() is the operation that closes streams. reset() rewinds() to marked state. It's described in Javadoc note on output2 implementation. But can implementation note prevail generic method contact - clears output pane? Now, I hope I have said everything I have wanted :-).
The reason is really thread safety: The writer operates over a memory mapped file full of data. The output window is a swing Document implmented over that memory mapped file. There are a number of optimizations that make a huge performance difference, which can only be done because it is known that the number of lines always goes up and never goes down. When the reset() is called, the data is going to be replaced BUT reset() can be called from any thread. When it is called, the Document being viewed will be replaced with a new one - but Swing is not thread safe, and this must be done in the EQ. So if the writer were "rewound", there would be a period of time when the Document was still visible (because the InvocationEvent to replace it hadn't run yet), but it was no longer backed by anything. One PaintEvent running before the InvocationEvent runs would do quite nasty things. I'm contemplating possibly wrapping the writer in a proxy writer, so it is always usable, and the Document is implemented over its wrapped writer, but I'm not sure this is even a good idea - the only reason people are having problems is by trying to do things that are either way too clever or clearly wrong (calling reset(); close(); was always a bug - it just didn't do anything bad in the old implementation).
Bloody issue, it randomly appeared again. I have reworkarounded using auxiliary println.
Created attachment 16662 [details] This would be a better approach
The problem is calling reset() on a writer that has never been used. I'll do something to make that a no-op. But anyway, that's your problem; the attached patch will fix it in a cleaner way.
Until it is fixed properly I am reopening this issue. In the current build the Check XML action prints nothing when it was called for the first time, then it appears randomly.
Tim, your patch does not work. It never reset()s.
OutWriter will now check if it's ever been written and ignore calls to reset() if it is unused. Checking in src/org/netbeans/core/output2/OutWriter.java; /cvs/core/output2/src/org/netbeans/core/output2/OutWriter.java,v <-- OutWriter.java new revision: 1.9; previous revision: 1.8 done
Verified in build 20040812-0503.
please see issue #47479 if it is not possible dup. In this case this one should be reopen
IMHO, it doesn't work in Beta1 candidate nor in current DEV (4.0) #20040818-1800 After you start ide and before you open any file in editor (but it might be left open from your previous session) and want to Check/Validate any xml/dtd file ... nothing is written into OutputWindow. You must first open any file in editor and then you've got result into lastly checked xml file.
*** Issue 47479 has been marked as a duplicate of this issue. ***
And in the console (when using TRUNK) is printed java.lang.Exception stacktrace which I'm attaching
Created attachment 16958 [details] exception stacktrace
Fixed in trunk. Now uses a wrapper writer class, so you can reuse a writer after calling reset() on it. Checking in demosrc/org/netbeans/core/output2/TestFrame.java; /cvs/core/output2/demosrc/org/netbeans/core/output2/TestFrame.java,v <-- TestFrame.java new revision: 1.13; previous revision: 1.12 done Processing log script arguments... More commits to come... Checking in src/org/netbeans/core/output2/AbstractLines.java; /cvs/core/output2/src/org/netbeans/core/output2/AbstractLines.java,v <-- AbstractLines.java new revision: 1.2; previous revision: 1.1 done Checking in src/org/netbeans/core/output2/Bundle.properties; /cvs/core/output2/src/org/netbeans/core/output2/Bundle.properties,v <-- Bundle.properties new revision: 1.7; previous revision: 1.6 done Checking in src/org/netbeans/core/output2/Controller.java; /cvs/core/output2/src/org/netbeans/core/output2/Controller.java,v <-- Controller.java new revision: 1.19; previous revision: 1.18 done Checking in src/org/netbeans/core/output2/ErrWriter.java; /cvs/core/output2/src/org/netbeans/core/output2/ErrWriter.java,v <-- ErrWriter.java new revision: 1.4; previous revision: 1.3 done Checking in src/org/netbeans/core/output2/FileMapStorage.java; /cvs/core/output2/src/org/netbeans/core/output2/FileMapStorage.java,v <-- FileMapStorage.java new revision: 1.7; previous revision: 1.6 done Checking in src/org/netbeans/core/output2/HeapStorage.java; /cvs/core/output2/src/org/netbeans/core/output2/HeapStorage.java,v <- - HeapStorage.java new revision: 1.4; previous revision: 1.3 done Checking in src/org/netbeans/core/output2/IOEvent.java; /cvs/core/output2/src/org/netbeans/core/output2/IOEvent.java,v <-- IOEvent.java new revision: 1.4; previous revision: 1.3 done Checking in src/org/netbeans/core/output2/NbIO.java; /cvs/core/output2/src/org/netbeans/core/output2/NbIO.java,v <-- NbIO.java new revision: 1.4; previous revision: 1.3 done Checking in src/org/netbeans/core/output2/NbIOProvider.java; /cvs/core/output2/src/org/netbeans/core/output2/NbIOProvider.java,v <-- NbIOProvider.java new revision: 1.6; previous revision: 1.5 done RCS file: /cvs/core/output2/src/org/netbeans/core/output2/NbWriter.java,v done Checking in src/org/netbeans/core/output2/NbWriter.java; /cvs/core/output2/src/org/netbeans/core/output2/NbWriter.java,v <-- NbWriter.java initial revision: 1.1 done Checking in src/org/netbeans/core/output2/OutWriter.java; /cvs/core/output2/src/org/netbeans/core/output2/OutWriter.java,v <-- OutWriter.java new revision: 1.13; previous revision: 1.12 done Checking in src/org/netbeans/core/output2/OutputDocument.java; /cvs/core/output2/src/org/netbeans/core/output2/OutputDocument.java,v <-- OutputDocument.java new revision: 1.7; previous revision: 1.6 done Checking in src/org/netbeans/core/output2/OutputTab.java; /cvs/core/output2/src/org/netbeans/core/output2/OutputTab.java,v <-- OutputTab.java new revision: 1.5; previous revision: 1.4 done Processing log script arguments... More commits to come... Checking in src/org/netbeans/core/output2/ui/AbstractOutputPane.java; /cvs/core/output2/src/org/netbeans/core/output2/ui/AbstractOutputPane. java,v <-- AbstractOutputPane.java new revision: 1.18; previous revision: 1.17 done Processing log script arguments... More commits to come... RCS file: /cvs/core/output2/test/unit/src/org/netbeans/core/output2/Lifecy cleTest.java,v done Checking in test/unit/src/org/netbeans/core/output2/LifecycleTest.java; /cvs/core/output2/test/unit/src/org/netbeans/core/output2/LifecycleTes t.java,v <-- LifecycleTest.java initial revision: 1.1 done Checking in test/unit/src/org/netbeans/core/output2/WrappedTextViewTest.java; /cvs/core/output2/test/unit/src/org/netbeans/core/output2/WrappedTextV iewTest.java,v <-- WrappedTextViewTest.java new revision: 1.3; previous revision: 1.2 done
TM=4.0 -> closing.