 I'm Dave, we can have a conversation, it's a small room, but you can treat me like a unidirectional resource if you prefer. It's actually not my first time in Singapore, it's my second time in Singapore, but last time I don't know, it was ages ago, so I'm sure everything has changed, all these buildings are probably new. Michael introduced me, anybody got any questions before I start? I don't know if it was advertised what I would speak about, I'm not sure I even knew until I got here. What I plan to do is show you some experiments I've been doing with Java templates. It doesn't have to be for web pages, but I'm going to show you some web page examples. You're probably already familiar with some of these templating technologies that are out there. One that a lot of people use is Timelief, anybody use Timelief? It's quite common, if you look at the PEC clinic, the vanilla PEC clinic is made out of Timelief. If we look at the Spring Boot source code, which I'm just doing here, then we'll see in the auto configuration, let's have a look in there, which are all this stuff. We'll see a few examples here. Is the font size okay for everyone? I'm not asking you to read the contents or anything. There's Timelief here somewhere, there we go. Timelief has some auto configuration in Spring Boot. What else is going to be there? Mustache. It wasn't in the Spring Framework before, but Spring Boot introduced Mustache as a sort of auto-configured template. I did that. I'm proud of it. I quite like Mustache. There's Free Marker, there's one of those here as well. That was always in Spring. I'm not speaking to this. Really? I can hear it really loud. I guess the problem is when I turn away from the microphone. It's really loud for me. It must be right behind me or something. I'm sorry. What was I saying? Free Marker was always in the Spring Framework that's been there for years. We had Velocity as well in Spring Boot, didn't we? I think Velocity was discontinued by Apache, so it no longer exists. We took it out of Spring Framework and we had to take it out of Spring Boot as well. Josh has a question. Without judging you much, but who's using JSP? Oh, JSP's. I forgot to even say. Nobody. Who knows what JSP's are? It would be great if somebody didn't, if nobody did. I unfortunately remember JSP's. There's also groovy templates here. I'm not sure many people use those, but it's another thing that's a feature of Spring Boot. All of those things are widely or less widely used. Actually, just before we move on from that, an example of using Mustache is... Why don't I talk about what the common features are? Common features are you write a template and then you render it by injecting a model. Java objects get mushed together with strings and you get HTML or something out. Of the examples we've talked about, JSP and Time Leap in particular are very much about HTML generation. You don't really see them used for anything else. You can, but they don't like it if you want to use them for email templates or documentation or something like that. Whereas the other examples I talked about are FreeMarker, Mustache, the groovy templates. They don't really care whether you're in a web application or not. You can use them to generate text, general text. I like that. That's one of the reasons I quite like Mustache. As an example, I thought I'd just point out if nobody knew this, Spring Rest Docs is a very useful and interesting project. It uses Mustache. If you go in the source code for Spring Rest Docs, if you ever need to extend it, you'll find out about it quite quickly. You can use Spring Rest Docs happily without knowing about the Mustache templates. They're here. If you looked at all of these snippets, they're actually written in Mustache. That's the Mustache syntax there for you, double braces. That's the Mustache, like somebody's literally on their face, Mustache. I'll give you that as an example and as a flavour of what a template looks like. This is going to render some markdown by looks of it. It's a table in markdown rendering the parameters to an HTTP endpoint. Parameters have a name and they have a description. This thing loops through all the parameters and printing out their name and description in a table. Neat and useful. I talked about some of the similarities and differences with the existing tools that I've mentioned in Spring Boot. Another thing they all share in common is that they are all basically runtime compilation steps. You fire up an engine, a template engine of some sort at runtime. It sucks in the strings, it parses them into some internal representation and then it mushes them together with the model. I think JSP is technically, you can pre-compile them. Sometimes people did, but they hardly ever did because really it's designed to be a runtime compilation step. In this day and age, Java 21 just came out. Grail VM was mentioned, native compilation was mentioned. It strikes me, we might want to think about a build time process, build time compilation of templates, both to improve performance and also to make them more accessible to native compilation. With Grail VM, if you compile a native image, I don't know if Josh is going to have this on his list of things to show. If you compile a native image, you have to teach it about all of the reflection that might happen inside your code. These template engines that we've talked about, especially the runtime compilation ones, they're very susceptible to needing reflection because when you render this parameters thing here, it's going to be a Java being getter, probably some object.get parameters method call. It's going to call that reflectively, isn't it? Which is okay because Java supports reflection, but these days we're all trying to look for faster and more efficient and more accessible to native compilation. It strikes me as worth looking for an option that is build time compilation and can therefore take into account the types and the structures of the data objects that you're going to use at runtime. I did some research, and this is what I came up with. You could find this, so I'm going to switch the ID in a minute, but this is where I've stashed the code. If you can't read that, I'm sorry, I can't increase the font size at the top there. It's in GitHub. This is a Java template demo, and the way I structured it, there's a main branch, which is going to be using a tool called JTE. If you look at the read me, it mentions JTE, and I stole this code from the JTE project. I didn't even write it myself, but I'm just collecting it in a convenient place for you. JTE is one of these build time compilation engines, and there are two other branches there. There's one called ROKER, and ROKER is another compile time template engine. I don't think it's Java only, but it has a Java implementation at least anyway. JSTATIO, I'm going to show you as well. Has anybody in the room ever used JTE, ROKER, or JSTATIO for anything? Great, so you're all going to be learning something new. That's fantastic. I think they all have some interesting things about them, but I'm going to say it before I start. JSTATIO is my favorite, and it's the one that I've actually contributed a little bit to myself. If you open up that project in an IDE, it'll look like this. This is on the main branch. Just check. I've got a Spring Boot application that really just is a Spring Boot application. It doesn't do anything. There's a sign here already that I'm going to have to do something special for native compilation, so I'm already adding runtime hints, so that's a hint, but I won't cover that yet. It has a controller. It's a normal web application. It's a very, very simple one. There's nobody else's sample. I just stole it from the internet. The main thing here is the home page is a get mapping, and as you can see, it returns a string called demo, and that's quite common in web applications that are used to the MVC programming model, the paradigm that everybody uses in Spring. You return the name of the view, and then there's a view resolver in Spring that maps that into an actual view representation. It's the same here. There is a view called demo, and that in this language corresponds to... I think this is just for the Maven tooling that they provide. They sort of have a default location which isn't in source main resources. It doesn't go in the class path because it's compiled at build time, so you don't need the templates at runtime at all. Here's an example. This one is called demo.jte. They have a default file and final name extension, and this is what the code looks like. It's quite intuitive. You can sort of see what's going on. It's Java-focused, so it has imports. It's a bit like JSPs, isn't it? Anybody who's used JSPs that don't seem to be very many people here who do, they would sort of recognise this. That's saying that demo model can be used like it can in a Java sort of style without the package name, and then I'm using that here to say this whole template requires a parameter of type demo model. This is how you sort of build... I don't really want to call it type safety, but type-typed model objects into the template. That's kind of the strength, I think, of jte, the way that it does that. Every time you want to refer to it, you do dollar brackets that are a bit like spring placeholders and dot-separated Java accesses. It could be public accesses or public bean accesses. That's basically it. The jte side of things, there isn't any auto-configuration for spring boot, obviously, for jte, so you have to do your own view resolver, view implementation, and I've got a little configuration file here that would be auto-configuration if it ever became part of spring boot, basically. It doesn't do very much. It's got two beans. It has a view resolver that translates strings into views, and it's got a template engine that helps the view resolver, basically, so it helps the mapping. If I was to... I probably don't have to run that, but the maven built, because it will already have been run here, but let's have a look to see what happened. Here's the target, right? This is stuff that has been generated. jte generated some stuff here. Can you see how it's generated? jte demo generated dot Java, and that's a naming convention that's built into the tooling. Again, you can change the names, I think, and the code there is generated at build time by a maven plugin. You could look at the POM file and you could work out what was going on. It's just a... It's an annotation processor, essentially. And that's it. I guess I should just prove that it works, right? It doesn't do very much like I showed you. This template is just going to say hello, and it's going to print a number. How many visits have you had? So let me just run that and make sure that it works. It is fast because the templates are all done at compile time. And then if I load this in the browser, this is what it looks like. You are... The French is from the original sample. It's not an homage to our hosts today. So yeah, that works, right? That's JT. So whatever you think about that, that's what it looks like. Then if I was to check out the... What was the other one? I said rocker. Rocker looks a bit different. So there's the application. This one doesn't have any runtime hints, so that tells you something, actually. The controller is kind of similar. There's the home page. It returns a string, and it sets up a demo model in the model of the model and view in the spring MVC terms. It's actually exactly the same controller. It would work. I think I've just added an extra step here. A special model attribute called arguments, but actually I didn't need to do that. It's very similar. Otherwise, you've got some configuration files. You've got a view resolver and a view implementation and some configuration to set that up. And when you run this one, so that one's no longer valid, when you run this one, you will get some generated Java code here. I've made this template slightly more interesting, so I could have done exactly the same, but I've made it slightly more interesting so I can show you something different. One of the features of rocker is this idea of a nested template. You can have a layout, which is common to all your pages. It's a very common pattern in the web. This one says every page is going to have HTML with the same head and a title, which is almost the same but is parameterised, and then a content body, which is at content. The content content is a special rocker body, which is like a lambda. I'll show you how it's implemented in a minute, and then you'll see what I mean. I've passed in arguments which are the title and the body that it wants to render. In the demo, there is only one body, and this looks very similar to the JTE example. It's got similar syntaxes at import, at args. The args are a type demo model, and in the demo model, you can do at model.visits instead of a dollar brace. It's very similar syntax, but not quite the same. Here's that little lambda thing that I was talking about. The rocker body is actually a lambda written in text. I'm not sure if I like that, but that's the way it works. You can write your lambas in line in the templates. That explains why in the generated code there are two Java source files. There's one for the outside template, the layout, and there's one for the nested one. I'll just demonstrate that it works. I'll run it, all of those. That's probably because it's still got stuff lying around from the previous demo. I'll just recompile everything. There we go. Of course, I'm back to visitor number one. That's the other demo, the new demo. It's a slightly different layout because the HTML is slightly different, but it's basically the same demo. Cool. Those are the two warm-up acts, if you like. The last one I want to show you is JStatio. I'm actually going to do this again as well to make sure everything gets rebuilt. JStatio, you can Google it. You'll find the project. JStatio does have spring boot auto configuration, so I don't need to write that stuff myself. All I need is the dependency, and it's an APT processor, so I have to make sure that the APT processor is on the class path or explicitly known to the compiler, but apart from that, it's very similar. It's very similar to the other two that I give you the architecture, the build setup, and it also has, like Rocker does, it has some natural nesting capabilities, and actually I found out, well, building these demos and some other apps using JStatio, I found out that these nested layouts, that pattern is actually part of the moustache spec. There's a spec for moustache. I think it came from Ruby on Rails and that side of the tracks, but it has a JavaScript. It has lots of different implementations, moustache, and so this is just one, and they're quite good at keeping to the spec. The existing Java implementation of moustache that we're using in Spring Boot, that's called JMoustache, that is a subset of the spec, so you can't do everything that you want to do in moustache using the JMoustache variant because it's kind of a dialect, it's a subset. One of the things it doesn't have is this nested layout thing. The way this looks in standard moustache is like this, so here's my layout. I haven't got anything in the head in this case, I'm just showing a parameterised body, so the body is a parameter of the layout of the template, and I say it's a parameter by using this dollar, it's a special symbol in the spec. And then in index, I say I want you to be a layout and I use the less than input to drag in the parent template, and then I declare the body parameter using the same dollar, so this is the body of the index page, and you can see it's the same, it's got a name and it's got a number of visits. So that's moustache, when it compiles, it compiles to generated code here under, this is the standard APT location for a Maven build, it compiles to something called a renderer, and so the renderer is, it takes a while to look at it, it's generated code so you never have to read it, but you might as well quickly take a look and see if you understand what's going on, and it is. The demo model, actually it's probably going to be full model.something, isn't it? So let's have a look for it. There we go, the model.class is boring. I wanted to show you an actual Java method call, so I know there's going to be a name, there we go, template name, not that one. What were my parameters? Visits and name, yeah, visits. Surely there's visits in there somewhere. Visits, there we go. So there's the generated code for that section of the template you see. You are visitor number, data.visits, there we go. So visits in this case, I was looking for model notes called data. Visits is a public long property of the demo model class, right? So it's being referred to in the generated code in a very explicit type-free compilable. You'll always see a compiler error if you get it wrong kind of way, right? So if I made a mistake in the template, I would get a compiler error. It's a build time compilation. Let's just make sure it works. Oh, so there's a little bit of configuration there. It's probably worth mentioning. So I think this is actually a default if you're using Spring Boot, but I'm telling it that my templates are in the standard Spring Boot location and they have a .moustache suffix. I'm telling it, yeah, there's some standard stuff that comes out of the java file. I'm telling it I want to see debug logging, and I'm telling it that the java time, local date can be formatted, i.e. you can just call two string on it. So that's like a security feature if you like. It's a white list. I'm saying you can just call two string on local date. It's fine. It's never going to blow me up. So there's a little bit of configuration to do there. And there we go. It's running and, of course, it's going to show me something very similar to the other examples. There we go. Mysterious business in number four. So I kind of like that. I like the fact that it's got spring support. I also like the fact that it's moustache, super moustache, so it's the full spec version of moustache. And if you wanted to see some more complex examples of that, there is one, for instance, Spring Pet Clinic. I know Michael probably knows all about these. The Spring Pet Clinic organisation, if you don't know about it. Is a community-driven github organisation that has different pet clinics. So we got tired of people in the Spring Pet Clinic asking for more and more features. So we said, OK, here, look, there's an org. You go and fill it with stuff. And so if you looked in here, you'll see, for instance, a moustache implementation. And that one is using the standard spring boot j-moustache. But there is also a branch of that called j-stache, which uses j-staches. So if you wanted to see a more complex example of that, you could look in there. You can see this by me. No surprise there. But you will see there, for instance, in the normal templates, moustache templates and fragments. So this is showing how you can do things like compose a field from reusable components, input fields and form components that I've written as separate layout, separate moustache templates. So yeah, I guess I'm kind of finished. But there's one last thing I wanted to say, to do with that native compilation thing. So it turns out that definitely JTE needed a bit of help with the native compilation. So although it's build time compilation, it still uses a bit of reflection around time. Actually, more than anything, just to find and create the template renderers because it still has this idea that you can turn a string into a view. Actually, if you look at it, it's worth looking at the controller. I didn't do that here with Jay Statcio. With Jay Statcio, you could do that, but you don't need to. So I'm just returning the model from my controller. And then Jay Statcio, instead of thinking, oh, you're giving me a string, I need to turn it into a template. It says, oh, you've given me a demo model and it's annotated with that Jay Statcio. So I can look up a renderer from that. It didn't need to use reflection because I can't even remember why. But it didn't need to use reflection because it can enumerate them in the same way that Spring can. It knows about the beans in the Spring context, so it can look them up in the context without using reflection. So there's never any reflection unless you explicitly want it in Jay Statcio. There are ways that you can use it, but the default is not. JayT is the opposite. It's quite reflection-ish when you get down to it. And I would say, Rock has sorted somewhere in the middle. I didn't need any runtime hints, but I don't think that's always the case. I just can't remember the details there, but it's kind of a spectrum there. There's a little bit of reflection needed in JTE and I think also in Rocker, but not in Jay Statcio. So I thought that was probably worth mentioning. All of those projects are quite keen on runtime performance and they think that it speeds things up. So they publish benchmarks where they compare themselves against the runtime compilation templates and they seem to do quite well in those benchmarks. I don't really know whether to believe benchmarks, honestly, because people are always trying to tell a story with them. But I think there's a good chance that, because it's a compile time step, it's a good chance that you'll enjoy using it. And so, do you ever try to get a chance? That's it from me. I'm going to hand this microphone over to Josh. Oh, this is the one that is being used by recording.