Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ResponseWriter.println(char) does not print newline #7031

Closed
mperktold opened this issue Oct 22, 2021 · 7 comments · Fixed by #7032
Closed

ResponseWriter.println(char) does not print newline #7031

mperktold opened this issue Oct 22, 2021 · 7 comments · Fixed by #7032
Assignees
Labels
Bug For general bugs on Jetty side

Comments

@mperktold
Copy link

Jetty version(s)
10.0.7

Java version/vendor (use: java -version)
openjdk version "11.0.9" 2020-10-20
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.9+11)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.9+11, mixed mode)

OS type/version
Windows 10, 64 bit

Description
When a single character is passed to response.getWriter().println, the newline after the character is not printed. In other words, for characters, print and println have the same effect.

Other overloads for other parameter types do not seem to have this problem, just character.

How to reproduce?

Call a servlet that writes single characters using response.getWriter().println(char) and verify the output.

@mperktold mperktold added the Bug For general bugs on Jetty side label Oct 22, 2021
@joakime
Copy link
Contributor

joakime commented Oct 22, 2021

This is quite the surprising issue.

For many reasons ...

  • We don't have a test case for this.
  • Nor do any of the other dozen open source projects that use Jetty that we build/test releases against.
  • Nor does the actual Servlet TCK have a test for this.

@joakime joakime self-assigned this Oct 22, 2021
@joakime
Copy link
Contributor

joakime commented Oct 22, 2021

So ...

The response.getWriter().println() and response.getWriter().println(char) are both implemented by javax.servlet.ServletOutputStream.
Both wind up calling javax.servlet.ServletOutputStream.println(String) with appropriate parameters. (this is the behaviour in Jakarta EE 8 / Jakarta Servlet 4.x, unknown if Java EE 7 / Servlet 4.x does the same, need to investigate)

The implementation of javax.servlet.ServletOutputStream.println(String) in Jetty is org.eclipse.jetty.server.HttpOutput.println(String).

I cannot see a bug there, as even the various small test of response.getWriter().println("X") (String vs char) would fail the same way.

@mperktold
Copy link
Author

I'm talking about this one in ResponseWriter:

    @Override
    public void println(char c)
    {
        try
        {
            synchronized (lock)
            {
                isOpen();
                out.write(c);
            }
        }
        catch (InterruptedIOException ex)
        {
            if (LOG.isDebugEnabled())
                LOG.debug("Write interrupted", ex);
            Thread.currentThread().interrupt();
        }
        catch (IOException ex)
        {
            setError(ex);
        }
    }

It only calls out.write(c) without writing a newline, whereas e.g. println(String) calls out.write(__lineSeparator); after writing the string.

I actually saw this behavior in a custom org.eclipse.jetty.server.Handler, not a servlet. Since both receive a HttpServletRequest, I assumed that the behavior would be the same for servlets, but perhaps I was wrong.

@joakime
Copy link
Contributor

joakime commented Oct 22, 2021

I'm in the process of improving code coverage for both response.getServletOutputStream() and response.getWriter() based actions.
This has already revealed more issues in other places.
Stay tuned for PR.

joakime added a commit that referenced this issue Oct 22, 2021
+ Improving test coverage on response.getWriter()
  and response.getOutputStream() usage

Signed-off-by: Joakim Erdfelt <[email protected]>
@joakime joakime linked a pull request Oct 22, 2021 that will close this issue
@joakime
Copy link
Contributor

joakime commented Oct 22, 2021

Opened PR #7032

@joakime
Copy link
Contributor

joakime commented Oct 22, 2021

Two bugs were found and fixed in PR #7032

  1. response.getWriter().println((char)c) would not include the System.lineSeparator().
  2. response.getWriter().println((boolean)b) would include System.lineSeparator() twice.

joakime added a commit that referenced this issue Oct 26, 2021
+ Improving test coverage on response.getWriter()
  and response.getOutputStream() usage

Signed-off-by: Joakim Erdfelt <[email protected]>
joakime added a commit that referenced this issue Oct 26, 2021
+ Improving test coverage on response.getWriter()
  and response.getOutputStream() usage

Signed-off-by: Joakim Erdfelt <[email protected]>
joakime added a commit that referenced this issue Oct 27, 2021
+ Improving test coverage on response.getWriter()
  and response.getOutputStream() usage

Signed-off-by: Joakim Erdfelt <[email protected]>
@joakime
Copy link
Contributor

joakime commented Oct 27, 2021

Some history, this bug was introduced in the Unchecked Print Writer commit 0dc3948 (introduced in Jetty 9.3.0)

This has been fixed in all active branches.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug For general bugs on Jetty side
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants