Please, Java. Do Finally Support Multiline String Literals

I understand the idea of Java-the-language being rather hard to maintain in a backwards-compatible way. I understand the idea of JDK API, such as the collections, to be rather tough not to break. Yes. I don’t understand why Java still doesn’t have multiline string literals. How often do you write JDBC code (or whatever other external language or markup, say, JSON or XML you want to embed in Java) like this?

try (PreparedStatement s = connection.prepareStatement(
    "SELECT * "
  + "FROM my_table "
  + "WHERE a = b "
)) {
    ...
}

What’s the issue?
  • Syntax correctness, i.e. don’t forget to add a whitespace at the end of each line
  • Style in host language vs style in external language, sure the above code looks “nicely” formatted in Java, but it’s not formatted for the consuming server side
  • SQL injection, didn’t we teach our juniors not to perform this kind of string concatenation in SQL, to prevent SQL injection? Sure, the above is still safe, but what keeps a less experienced maintainer from embedding, accidentally, user input?
Today, I was working with some code written in Xtend, a very interesting language that compiles into Java source code. Xtend is exceptionally useful for templating (e.g. for generating jOOQ’s Record1Record22 API). I noticed another very nice feature of multi line strings: The lack of need for escaping! Multi line strings in Xtend are terminated by triple-apostrophes. E.g.

// Xtend
val regex = '''import java\.lang\.AutoCloseable;'''

Yes, the above is a valid Java regular expression. I’m escaping the dots when matching imports of the AutoCloseable type. I don’t have to do this tedious double-escaping that I have to do in ordinary strings to tell the Java compiler that the backslash is really a backslash, not Java escaping of the following character:

// Java
String regex = "import java\\.lang\\.AutoCloseable;";

So… Translated to our original SQL example, I would really like to write this, instead:

try (PreparedStatement s = connection.prepareStatement(
    '''SELECT *
       FROM my_table
       WHERE a = b'''
)) {
    ...
}

With a big nice-to-have plus: String interpolation (even PHP has it)!

String tableName = "my_table";
int b = 1;
try (PreparedStatement s = connection.prepareStatement(
    '''SELECT *
       FROM ${tableName}
       WHERE a = ${b}'''
)) {
    ...
}

Small but very effective improvement

This would be a very small (in terms of language complexity budget: Just one new token) but very effective improvement for all of us out there who are embedding an external language (SQL, XML, XPath, Regex, you name it) in Java. We do that a lot. And we hate it. It doesn’t have to be as powerful as Xtend’s multiline string literals (which really rock with their whitespace management for formatting, and templating expressions). But it would be a start. Please, make this a New Year’s resolution! :)

31 thoughts on “Please, Java. Do Finally Support Multiline String Literals

  1. I am not against the multi-line string feature, but you don’t have to wait for anything – just use a proper IDE :-)

    That will solve at least some of your issues:
    – syntax highlighting and correctness (table and column names included!!)
    – some kind of “edit fragment” feature should do the escaping automatically (in regexes as well as in sql)

    I am not sure what you mean by the style (2nd bullet point), and how it would change with string interpolation).

    I wouldn’t worry too much about the SQL injection – as you are already using prepared statement anyone with a bit of sense will use that properly. And checkstyle/findbugs to the rescue if they don’t.

    I am sure you know what IDE I am talking about :-).

    1. Indeed, that “proper IDE” does help a bit. But I’m talking about the possibility of implementing a complex query in SQL Developer and then just copy-pasting it into my Java program. Or XML. Or JSON. Or properties. Or any other external DSL that I want to inline with Java code.

      And: I most certainly don’t want to escape anything, just because I’m putting it in a Java string that reserves the quote and backslash characters!

  2. I’m personally a fan of C# Syntax.

    @”Multi-line string with no need for escaping things here”

    ‘Regular string where you need to escape here”

    String interpolation is nice though – a bit nicer than the {0} syntax of String.Format.

  3. You realize your hypothetical multi-line string with interpolation Java example is _exactly_ the kind of string concatenation you should not do because injection?

    1. How else would you dynamically insert a table in your SQL string?

      Granted, the multiline string literal version is just as good as the alternative concatenated version. But without concatenation, I claim there would be less accidents.

      1. “How else would you dynamically insert a table in your SQL string?”

        … with JPA and Criteria API. But you have to desing carefully the DB schema.

        1. You’re on the jOOQ blog. jOOQ got embedding arbitrary expressions (such as column, table, schema, catalog references) right as well, probably much more thoroughly than Criteria API.

          But we’re talking about embedded native SQL here. At some point, even jOOQ can’t model a complex SQL statement any longer, in case of which you will inevitably need to resort to strings.

    1. Ceylon indeed did get a lot of things very right. Interestingly, Ceylon’s multiline String format could be retrofitted into Java backwards-compatibly.

  4. Nice point Lukas, indeed idea of three quotes make a lot more sense than using + for concatenation. I have myself forgotten to add whitespace so many times :)

    1. That’s an option, of course. But I’m not so sure if these approaches scale well. Somehow, there hasn’t been any popular Java code preprocessor in the last 20 years. Even SQLJ is pretty dead.

  5. An eclipse plugin is spectacularly useless for any project that wants to compile code without using eclipse – continuous integration, commandline, every other IDE, etc.

    Similarly, the idea of using an IDE to auto-format the string with all of the extra java noise that will make it compile completely defeats the purpose of wanting to be able to move strings bidirectionally. Sure, an IDE makes it easy to paste a multiline string into your code, but now let’s assume you want to execute that SQL query in your db’s terminal client a month after it was pasted into your source code, how will you do that? You have to paste, then carefully edit every single line. The same goes for JSON and HTML multiline content, which often wants to get pasted into a browser.

    It is mindboggling that the java ecosystem still has no built-in solution for this other than to use (every other available) JVM-based language to implement any class that requires multiline strings. It’s not as though this problem didn’t exist, with solutions, even before the Java language existed, let alone between the first release and JDK 8, a period of time which allowed pretty much every other computer programming language on earth to acquire some kind of native support for multiline strings.

    1. a period of time which allowed pretty much every other computer programming language on earth to acquire some kind of native support for multiline strings.

      Multiline strings predated Java. Take SQL, for instance… ;)

    1. That’s a very interesting approach, thanks for sharing! How does it work? Do you run some compiler preprocessor to transform the comments into JDBC code? What made you roll your own rather than, e.g. use SQLJ (https://en.wikipedia.org/wiki/SQLJ), which would be the SQL standard approach to this technique?

Leave a Reply to Will Sargent (@will_sargent)Cancel reply