pre-RFR (s): 8049847: Enhance PrintWriter line.separator handling
Claes Redestad
claes.redestad at oracle.com
Sun Jan 4 14:10:32 UTC 2015
On 2015-01-04 11:06, Alan Bateman wrote:
> On 02/01/2015 15:38, Claes Redestad wrote:
>> Hi,
>>
>> this is a proposal to resolve concerns that
>> PrintWriter/BufferedWriter behave
>> inconsistently with j.u.Formatter when setting the line.separator
>> property to override
>> system-appropriate line breaks.
>>
>> Instead of providing a set of new constructors, I propose to simply
>> add a new default
>> method j.l.Appendable#lineSeparator, which by default delegates to
>> System.lineSeparator().
>> This allows classes such as PrintWriter/BufferedWriter to provide
>> overrides which
>> communicate to j.u.Formatter their intended behavior.
> In the bug report then I assume the inconsistency only arises because
> the test case attempts to change the line separator in the main
> method, which is too late. It should work if set on the command-line
> but this of course sets it system-wide.
Right, the PrintWriter inconsistency detailed:
- methods format/printf uses j.u.Formatter, which uses
System.lineSeparator() internally if it
encounters an "%n" in the format string. Only responds to when changing
line.separator on
command-line or similar.
- methods println and newLine use the PrintWriter internal lineSeparator
value evaluated at
object creation time:
public PrintWriter(Writer out,
boolean autoFlush) {
super(out);
this.out = out;
this.autoFlush = autoFlush;
lineSeparator = java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("line.separator"));
}
This leads to hacks existing in the wild which sets line.separator
before creating the PrintWriter,
as exemplified here:
http://stackoverflow.com/questions/1014287/is-there-a-way-to-make-printwriter-output-to-unix-format
Removing this functionality could break compatibility with some
applications where developers
are intentionally changing the line.separator, while it'd be nice if
there was a better way to facilitate
this, which I think my proposal would allow with minimal
>
> Your proposal to add a lineSeperator() method to Appendable would
> allow for customization but I'm not sure that it's the right place (as
> Appendable is a very general interface and would require every
> Appendable implementation that writes lines to be updated to make use
> of the new method).
Yes, this can seem an awkward place to add this method, but the only
place where we'd be able
to as easily make java.util.Formatter use the custom lineSeparator,
without which we wouldn't
be able to resolve the inconsistency above nor provide a more convenient
way for developers
to avoid the line.separator hack.
However, since Appendable is defined rather strictly-coupled with
java.util.Formatter ("The Appendable
interface must be implemented by any class whose instances are intended
to receive formatted
output from a java.util.Formatter.") and Formatter provides a
higher-order mechanism to print new-lines
("%n") to the Appendable, it doesn't feel entirely arbitrary that the
lineSeparator behavior should be
accessible via Appendable.
>
> An alternative to consider is adding the notion of lines to
> java.io.Writer and update it to define newLine() and lineSeperator()
> methods (i.e. move the BufferWriter::newLine method up to Writer).
> It's a bit of extra work to update BufferedWriter's spec, adjust a few
> things in PrintWriter/PrintStream, and special-case Writers in
> Formatter but something to consider.
I need to think about what that would mean, and especially how to solve
it on the Formatter side.
I worry shoehorning Writer or upcasts into Formatter might be more
complex that it's worth.
Any ideas?
/Claes
>
> -Alan
More information about the core-libs-dev
mailing list