• Post Reply Bookmark Topic Watch Topic
  • New Topic

Second XMLEncoder Silently Dies on Shared Stream  RSS feed

 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My adventures with XMLEncoder continue...

I've got a simple main routine that instantiates two structurally identical classes, and attempts to write them both out to System.out with an XMLEncoder:


I expected Line 16 and Line 24 to both write some XML-formatted output, looking very similar to each other. But here's my output:



Now, if I change Line 24 so that the second call to writeObject is to a different stream("23. XMLEncoder e2 = new XMLEncoder(System.err);"), I do get both outputs:



So, I am inferring that this means two XMLEncoder objects can't both hold references to the same OutputStream, even if the first object is closed before the second is created. In actual practice, I guess I can live with that, since I wouldn't write the XML-encoded version of two objects to the same stream (I'd get the header twice in the same file, and I believe that's a no-no). But I am surprised that this doesn't generate some kind of exception, either when the second XMLEncoder is constructed, or when its writeObject method is called. But, it just silently dies.

(In anticipation of anyone asking why I am writing the output to System.out: so I can see it as I debug some code that will be writing to a disk file later.)
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ah, as usual, the answer was in the XMLEncoder doc. I was just looking in the wrong place:

public void close()
This method calls flush, writes the closing postamble and then closes the output stream associated with this stream.


For my debugging, the solution is to replace that first call to e.close(), at Line 17, with a call to e.flush(). Not sure how I feel about a method closing an output stream for a class whose methods didn't open the stream. Is that common?
 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16059
88
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would say that it isn't really good design if a class that doesn't "own" the OutputStream closes it for you. Note that Java's standard library isn't always the greatest source for examples of good class design - some of the classes in the standard library have horrible design mistakes.

On the other hand, why would you want to write anything to the OutputStream after XMLEncoder has written a complete document to it? There should normally not be any data after the closing tag of the root element of the XML document.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jesper de Jong wrote:I would say that it isn't really good design if a class that doesn't "own" the OutputStream closes it for you. Note that Java's standard library isn't always the greatest source for examples of good class design - some of the classes in the standard library have horrible design mistakes.

You know, that is very heartening to read. I tend to think the standard library is pretty impressive, and my Java is always getting better, so I am reluctant to conclude that the library code isn't perfect. But, sometimes... well, you just find things you think aren't what they should be. Glad to know I may not always be wrong about that.

On the other hand, why would you want to write anything to the OutputStream after XMLEncoder has written a complete document to it? There should normally not be any data after the closing tag of the root element of the XML document.

Like I said, I'm just debugging things. None of this is for production purposes. I've been comparing/testing a variety of ways to use XMLEncoder, all of which should produce the same output. If they don't, I know at least one of them has a bug. Rather than write to files and open them over and over, it's just easier to have it spray all that XML directly onto my screen.

Replacing all calls to XMLEncoder's close with calls to its flush method is working. (In production, I may end up using try-with-resources, which will close the stream for me; that should work too since, as you point out, it is senseless to write anything after the root element.)
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!