Showing posts with label Freemarker. Show all posts
Showing posts with label Freemarker. Show all posts

Thursday, 13 October 2022

Why don't record classes follow the Java Bean conventions?

Records are named tuples1.

Notice that the name of the field accessors does not start with get and, therefore, does not conform to the JavaBeans conventions.

We can declare getter methods if we really want to, and let them refer to the record method, but I'd opt not to if possible. We can do it, for a little while, until frameworks catch up to the new code convention, which will be pretty quick.

As Brian Goetz wrote in an online thread2:

“. . . the language has a responsibility to look forward as well as backward, and balance the needs of existing code with the needs of new code. Taking a bad library naming convention and burning it into the language forever would have been the worse choice.”

Builders

We can create builders for Records, if we like. See [3] for instance, but I'm not a fan of automatic code generation.

FreeMarker

The reason I started on this blog, is because there's a plethora of different frameworks/tools/what-have-you available that all center around the Java Beans conventions.

In most cases, records are not a good fit for these, as those frameworks and tools operate on the notion that these are mutable data classes.

But sometimes, there are definitely simple use cases where it would come in handy.

For example with the use of Freemarker4, a templating engine that converts your templates and Java POJOs to nice html pages (or other kinds of pages, there's no limit really).

And these follow the getX() convention.

So, one way would be to create the blasted getter methods in the Record class, but then you're adding boilerplate again, and I feel uncomfortable with that.

Perhaps an idea is to create my own DefaultObjectWrapper5.

So, Freemarker will need some changes to support record classes6. Something like automatically generating a hashmap of all the methods that have no arguments, yet return something... and preferable do not start with get?

References

[1] Data Classes and Sealed Types for Java - Brian Goetz February 2019
https://openjdk.java.net/projects/amber/design-notes/records-and-sealed-classes
[2] ForumPost - Feedback for records: Accessors name() vs. getName()
https://mail.openjdk.java.net/pipermail/amber-dev/2020-August/006414.html
[3] GitHub - RecordBuilder
https://github.com/Randgalt/record-builder
[4] FreeMarker
https://freemarker.apache.org/
[5] FreeMarker - Object wrappers
https://freemarker.apache.org/docs/pgui_datamodel_objectWrapper.html#pgui_datamodel_defaultObjectWrapper
[6] Apache JIRA - FREEMARKER-183
https://issues.apache.org/jira/browse/FREEMARKER-183
JLS - 8.10. Record Classes
https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-8.10
JavaMagazine - Records Come to Java
https://blogs.oracle.com/javamagazine/post/records-come-to-java
JavaMagazine - Java records: Serialization, marshaling, and bean state validation
https://blogs.oracle.com/javamagazine/post/diving-into-java-records-serialization-marshaling-and-bean-state-validation

Thursday, 31 October 2019

Freemarker and java.time

I noticed that Freemarker1 does not yet support the Java SE 8 Date and Time2. I noticed this, because I tried it. It just tries to parse the toString() and it fails.

There's already blogs about it.

So I had to add a little dependency to provide this, courtesy of Jakob Vad Nielsen3.

<dependency>
    <groupId>no.api.freemarker</groupId>
    <artifactId>freemarker-java8</artifactId>
    <version>1.1.5</version>
</dependency>

Of course, it's not native support, you still have to call specific methods to parse this. But it works in my case.

It means I have to change some of my templates around, as described below:

Published Date ${blog.createDate?datetime}
Instead should be:
Published Date ${blog.createDate.format()}

References

[1] FreeMarker Java Template Engine
https://freemarker.apache.org/
[2] Java Technical Details - Java SE 8 Date and Time
https://www.oracle.com/technical-resources/articles/java/jf14-date-time.html
[3] GitHUb - Java library adding support for the Java 8 java.time api to FreeMarker.
https://github.com/lazee/freemarker-java-8