0

I am in the process of learning how to cope with java 14 (preview) text blocks. When using following text block in a Junit test I run across the following unexpected feature (simplified code example, in the real test I use an HTML fragment):

assertEquals("""
    test""", "test");

Executing this test results in an error since "\r\ntest" does not match "test":

org.junit.ComparisonFailure: expected:<[
]test> but was:<[]test>

When I consult the documentation (https://docs.oracle.com/javase/specs/jls/se14/preview/specs/text-blocks-jls.html), it literally states:

The content of a text block is the sequence of characters that begins immediately after the line terminator of the opening delimiter, and ends immediately before the first double quote of the closing delimiter.

Did I miss something?
Update after several questions and suggestions:
I create a small test class:

public class Tester {

    public static void main(String[] args) {
        System.out.println(">>" + """
            test""");
    }
}

which, when executed, prints the following:

>>
test

The bytecode of this class is

Compiled from "Tester.java"
public class nl.paul.testapp.testutil.Tester {
  public nl.paul.testapp.testutil.Tester();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #13                 // String >>test
       5: invokevirtual #15                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}
howlger
  • 31,050
  • 11
  • 59
  • 99
PaulN
  • 63
  • 2
  • 10
  • 1
    shouldn't you simply use `"""test"""` for it to have no newline, currently it seems like you did add a linebreak? – Lino Jun 08 '20 at 13:26
  • The text block starts immediately after `"""`. And the first thing after that is a line break in your example. You can put the `"""` on a new line too or use `trim()` – bb1950328 Jun 08 '20 at 13:28
  • There's a leading new line, because you have a leading new line in your block. That's the point of text blocks. Having multi-lined Strings without the need for escaping. – QBrute Jun 08 '20 at 13:30
  • 2
    The docs (https://docs.oracle.com/javase/specs/jls/se14/preview/specs/text-blocks-jls.html#jls-3.10.6) require me to add a newline after the initial """. Besides, as stated in my question, in the real test I use an HTML snippet with included newlines... – PaulN Jun 08 '20 at 13:31
  • 2
    Are you compiling in Eclipse? This seems like a bug. You might want to edit the JLS quote into your question. – Sotirios Delimanolis Jun 08 '20 at 13:43
  • Specifically: _The content of a text block is the sequence of characters that begins immediately after the line terminator of the opening delimiter, and ends immediately before the first double quote of the closing delimiter._ – Sotirios Delimanolis Jun 08 '20 at 13:44
  • Indeed I am compiling in Eclipse (2020-03 (4.15.0)) using OpenJDK 14.0.1. I updated the question conform your advice. – PaulN Jun 08 '20 at 14:17
  • Could you check the bytecode to see what the string literal placed by the JVM looks like? – Lino Jun 08 '20 at 14:23
  • What did you insert, `\r\n` and what did you get back? – matt Jun 08 '20 at 14:24
  • When I try creating a string like your test string and checking the length, it works fine. OpenJDK Runtime Environment AdoptOpenJDK (build 14.0.1+7). – matt Jun 08 '20 at 14:52

3 Answers3

2

At last, the problem is clear. It is Eclipse related. When I compile and run the code from a command prompt (same java version as Eclipse uses), everything works as expected. When I compile and run the same code from within Eclipse, the text block is prepended with \r\n.
I will edit the question phrasing.

PaulN
  • 63
  • 2
  • 10
  • TL;DR Eclipse uses [JIT Compiler](https://www.eclipse.org/openj9/docs/jit/) which can cause problems in some scenario. – Aniket Sahrawat Jun 08 '20 at 16:05
  • @AniketSahrawat JIT isn't limited to eclipse. hotspot jvm also uses JIT. – matt Jun 08 '20 at 16:19
  • @AniketSahrawat The OpenJ9 JIT compiler you refering to executes bytecode (part of the OpenJ9 Java VM and an alternative to the HotSpot VM) and is not related to the Eclipse IDE containing the Eclipse compiler for Java (ecj) which creates bytecode and which is an alternative for `javac`. All this mentioned software contains bugs and known issue, so make sure to always use the latest release (which is not the case here). – howlger Jun 08 '20 at 17:23
2

Eclipse 2020-03 (4.15) does not support Java 14. You have installed Java 14 Support for Eclipse 2020-03 (4.15) from the Eclipse Marketplace, which is the preview/beta version of the upcoming Java 14 support of Eclipse 2020-06 (4.16) which will be released on June 17th, 2020.

In the current release candidate, Eclipse 2020-06 (4.16) RC1, it works as expected. So it is a already fixed Eclipse Compiler for Java (ecj) bug in a build, not in a release (according to the Eclipse Development Process).

The Marketplace entry still refers to an outdated preview version and will probably be updated shortly after the release (as it happened with other new supported Java versions before).

Please note, text blocks are preview features of Java 13 (first preview) and Java 14 (second preview; improved) and therefore not yet part of a Java language specification. It is not intended to be used in production.

howlger
  • 31,050
  • 11
  • 59
  • 99
  • 1
    I'm using Eclipse 4.14.0. It compiles text blocks as expected, without starting new lines. – ZhekaKozlov Jun 09 '20 at 04:11
  • @ZhekaKozlov Then you use text blocks of the preview features of Java 13, which are different from text blocks of the preview features of Java 14 (which this question is about). – howlger Jun 09 '20 at 06:44
  • Text blocks in Java 14 are mostly the same as 13's text blocks. The difference is in two additional escape sequences. The other rules are exactly the same (new line handling etc). – ZhekaKozlov Jun 09 '20 at 09:13
  • @ZhekaKozlov There are no text blocks in Java yet. Text blocks are planned for Java 15, which will be released in September. Eclipse JDT 4.14 and 4.15 support the preview features of Java 13 and Eclipse JDT 4.16 will support the preview features of Java 14, but not of Java 13. The question is about Eclipse 4.15 with probably the Java 14 beta plug-in of an unknown build (so preview features of Java 14, not of Java 13). Sure, you might say that all of these things are almost the same, but _almost the same_ is not the same as _the same_. – howlger Jun 09 '20 at 09:40
  • 1
    Updating Eclipse indeed fixed the problem. Thanks for pointing out. – PaulN Jul 08 '20 at 09:53
0

It looks you're doing something wrong. The JLS says:

The content of a text block is the sequence of characters that begins immediately after the line terminator of the opening delimiter, and ends immediately before the first double quote of the closing delimiter.

JEP 378 (Text Blocks) confirms it:

The opening delimiter is a sequence of three double quote characters (""") followed by zero or more white spaces followed by a line terminator. The content begins at the first character after the line terminator of the opening delimiter.

...

"""
line 1
line 2
line 3
"""
is equivalent to the string literal:

"line 1\nline 2\nline 3\n"

I also checked it on my machine:

System.out.println("""  
        test""".equals("test")); // Prints true
ZhekaKozlov
  • 36,558
  • 20
  • 126
  • 155
  • _It looks you're doing something wrong_ that's the key you're missing. They've already mentioned everything you say in their question/comments. – Sotirios Delimanolis Jun 08 '20 at 14:24
  • This is really weird, when testing your System.out etc. My machine prints "false"... I will further investigate conform above questions on Bytecode etc. Are you on *nix or windows? I am working on windows 10. – PaulN Jun 08 '20 at 14:43
  • This question is about Java 14, not Java 13. So it's [JEP 368](https://openjdk.java.net/jeps/368) (second preview), not JEP 378 (first preview). – howlger Jun 09 '20 at 06:48
  • Your first quote is not from the JLS, but from a ["document proposes changes to The Java(R) Language Specification"](https://docs.oracle.com/javase/specs/jls/se13/preview/text-blocks.html) of Java SE 13. – howlger Jun 09 '20 at 09:56
  • @howlger [Java SE 14 spec](https://docs.oracle.com/javase/specs/jls/se14/preview/specs/text-blocks-jls.html) has the same paragraph. – ZhekaKozlov Jun 09 '20 at 11:59
  • You wrote, "The JLS says". But the JLS doesn't say it (yet). Text blocks are still draft. It's not wrong what you say, it's just not relevant since the question is about a different text blocks draft. And no one doubts that they will work as you have described. It seems the question is about a temporary ecj bug of an unknown build (not of a release). – howlger Jun 09 '20 at 13:03
  • @howlger Preview features are part of JLS. They are just not permanent. – ZhekaKozlov Jun 09 '20 at 13:17
  • @ZhekaKozlov No, preview features are not part of JLS. They are proposals of not yet applied JLS changes. At the beginning of each of these preview feature specs there is a note (_This document..._) that leaves no doubt about this. – howlger Jun 09 '20 at 13:48
  • @howlger Please read [JEP 12](https://openjdk.java.net/jeps/12). The part that starts with _"3. Universally available. The Umbrella JSR for the Java SE $N Platform enumerates..."_. – ZhekaKozlov Jun 09 '20 at 13:55
  • @ZhekaKozlov None of this says so. _"The Text Blocks preview feature spec says"_ would be more accurate than _"The JLS says"_ for your first quote. – howlger Jun 09 '20 at 14:35