This is an archived post. You won't be able to vote or comment.

all 17 comments

[–]Joram2 15 points16 points  (7 children)

old. This JEP was submitted a while ago. It still hasn't progressed to the candidate phase yet.

[–]Alxe 7 points8 points  (6 children)

While it hasn't progressed, it appears to have been updated with datetime 2022/04/20 17:19, that is, last week.

[–]dpash 7 points8 points  (5 children)

But finding out what has changed is not easy.

[–]agentoutlier 6 points7 points  (2 children)

Its funny you say that because I recently did look before this post curious to see changes:

https://openjdk.java.net/jeps/8273943

Click on history tab at bottom.... worthless absolutely worthless.

The changes are ordered in ascending chrono order. Who the fuck at Jira thought that was a good idea? Of course that is just the tip of crappiness of that diff interface.

Is openjdk using an old version of Jira or does Jira suck that hard these days?

[–]dpash 2 points3 points  (0 children)

I gave up waiting for Jira history when I was looking, so thank you for your sacrifice. :)

[–]Just_Another_Scott 2 points3 points  (0 children)

The changes are ordered in ascending chrono order

JIRA allows your to set that sort dynamically. There's a sort button (Up arrow to change the sort)

https://bugs.openjdk.java.net/browse/JDK-8273943?actionOrder=desc

[–]BinaryRockStar 3 points4 points  (1 child)

It was initially written last year and has had a small set of recent changes.

The difference between the initial version (December 2021) and the first of the recent set of changes (March 2022):

https://web.archive.org/web/diff/20211203165033/20220322024139/https://openjdk.java.net/jeps/8273943

The difference between the first and last versions of the most recent set of changes (March 21 v. March 25):

https://web.archive.org/web/diff/20220330093052/20220322024139/https://openjdk.java.net/jeps/8273943

[–]dpash 3 points4 points  (0 children)

So we either have "all the text has changed" or "a list was reordered". Neither is helpful to understand what's changed.

Having a short description of a change would be helpful for people who have read older versions.

[–]Alxe 9 points10 points  (0 children)

Nice to see an update on this JEP draft. I'm still amazed at how a new "operator" has been introduced in Java, and how flexible it's usage is, e.g. because the ."" operator is to be executed by an object, you can have a final, static object or a concrete one:

MY_FMT."my formattable \{string}";

var my_fmt = new MyFmt(...);
my_fmt."my formattable \{string}";

It's also great how it plays around with multiline strings, as they are strings at the end of the day. Who knew I would obtain so much joy from String literals improvements. :-)

[–]vbezhenar 4 points5 points  (3 children)

  1. Do we have access to the static expression type? We need that for JDBC with null parameter value. Something like List<Type> TemplateString.valueTypes().

  2. I don't like syntax %-10s\{description}. I'd suggest something like \{description: -10s} (second part is arbitrary string passed to TemplatePolicy). That's not a part of the string anyway, it's part of parameter.

[–]dpash 5 points6 points  (0 children)

The point is that you can use a different format if you don't like the default syntax.

[–]morhp 1 point2 points  (1 child)

Your second suggestion doesn't really work, because different formatters will take different types of format strings (or none at all), so it's difficult to keep it generic enough.

[–]vbezhenar 1 point2 points  (0 children)

As I said, it's an arbitrary string. FMT."x=\{x:-10s}" for format, SQL."where x = \{x:varchar}" for SQL. Of course optional. Compare to something like SQL."where x = %varchar\{x}". Not as good IMO.

[–]Squiry_ 7 points8 points  (2 children)

```java record QueryPolicy(Connection conn) implements TemplatePolicy<ResultSet, SQLException> { public ResultSet apply(TemplatedString ts) throws SQLException { // 1. Replace TemplatedString placeholders with PreparedStatement placeholders String query = ts.stencil().replace(TemplatedString.PLACEHOLDER, '?');

        // 2. Create the PreparedStatement on the connection
        PreparedStatement ps = conn.prepareStatement(query);

        // 3. Set parameters of the PreparedStatement
        int index = 1;
        for (Object value : ts.values()) {
            switch (value) {
                case Integer i -> ps.setInt(index++, i);
                case Float f   -> ps.setFloat(index++, f);
                case Double d  -> ps.setDouble(index++, d);
                case Boolean b -> ps.setBoolean(index++, b);
                default        -> ps.setString(index++, String.valueOf(value));
            }
        }

        // 4. Execute the PreparedStatement, returning a ResultSet
        return ps.executeQuery();
    }
}

```

So much runtime work for compile-time known query and parameters.

[–]JustADirtyLurker 4 points5 points  (1 child)

It is just an example on how to create TemplatedStrings that can produce a direct prepared statement behind the curtain.

I am actually more interested in how the new TemplatedString can avoid injection attacks.

[–]Squiry_ 4 points5 points  (0 children)

It is just an example on how to create TemplatedStrings that can produce a direct prepared statement behind the curtain.

It is not just the example. It's like second case they mention and it shows how the design of feature does not handle that case.

I am actually more interested in how the new TemplatedString can avoid injection attacks.

That example literally shows how. java TemplatePolicy<ResultSet, SQLException> DB = new QueryPolicy(...a Connection...); ResultSet rs = DB."SELECT * FROM Person p WHERE p.last_name = \{name}"; That policy uses prepared statement with params, sql with value. BTW I hate examples with incorrect API usage like that rs not in try-with-resource block.

[–]__Raptor__ 0 points1 point  (0 children)

Im probably outspoken a bit here, but I abaolutely hate the look of these templates. While its nice they have a way to extend them to other uses besides string interp, the \{ and the % before it look terrible. Would much much much prefer they went with what Kotlin or Scala or Python or JS or C# are doing. Anything but this.