Reading J2HTML

J2HTML (j2html) is a Java library used to generate HTML I have been using it to create Web 1.0 applications in Java. Web 1.0 is server-side rendering pages with minimal Javascript.

As I got deeper into using the library I started to read the actual source code of this library with an eye on following Java best practices and to my pleasant surprise, this code follows many of them.

I am going to show here some examples of using interesting Java features, beyond the basics.

1. Functional Interface

People are aware that Java supports some form of Functional Programming, and here is an example of using it:


public interface Indenter {

    String indent(int level, String text);


public static Indenter indenter = (level, text) -> String.join("", Collections.nCopies(level, FOUR_SPACES)) + text;

Things that I noticed:

  • String has a method called join. I used before StringUtils.join, but now that is in the standard library I don’t need to use that anymore

  • Collections has the method nCopies, never used it but clever to have it here

2. Passing Configuration to Inner Methods

Passing configuration to various methods is always complicated because:

  • If we use parameters then there are more and more parameters to pass

  • Or, we use a static class or thread-storage we add configuration but this just hides a dependency. This is called “Ambient Context” anti-pattern.

  • Or we use a property with a reasonable default in classes that need it.

J2HTML uses the third approach. There is a class called Config. This is passed as parameter in the Builder constructor and has a “good” default.

Some ideas from the Config class:

  • All the “good” defaults are exposed as public

  • There is a “defaults” method that returns a Config with the “good” defaults

  • Has a static factory method called global

  • All the operations on config are “copy on write” this avoids concurrency issues

  • The HtmlBuilder gets the config in the constructor and is optional. If not present it gets the defaults.

3. Renderable, Appendable

J2HTML uses several “marker” interfaces.

Renderable is an interface shared by all the Tags, DomContent. Given a builder it will return a string.

public interface Renderable {

    default <T extends Appendable> T render(HtmlBuilder<T> builder, Object model) throws  IOException;


There are a few assumptions in this interface:

  • All the builders will be HTML builders

  • The parameter of the render method is the output type which is appendable (e.g. StringBuilder, StringWriter)

4. Recursive Type Bound

In a few places I see a parameterized class definitions like these:

public abstract class Tag<T extends Tag<T>> extends DomContent  {



public class ContainerTag<T extends ContainerTag<T>> extends Tag<T> {



public class PTag extends ContainerTag<PTag> {

  public PTag() {




These kinds of definitions are useful to implement fluent APIs that are at the same time typesafe. Another advantage is that the autocomplete will show only the appropriate methods.

A good explanation of why this is useful is in this Stack Overflow article:

5. No Components

While j2html has many useful and interesting abstractions, it does not have a component model or abstractions to convert business objectives into HTML code. This has to be done by the application developer.

Popular posts from this blog

Performance Testing a New CRM

On Defining Messages

What Can Category Theory Do for Me?