Search code examples
javaspringthymeleaf

Why can't I reference my nested class in thymeleaf?


I have a nested class structure with multiple levels like this:

public class L1 {
  public static class L2 {
    public static class L3 {
      public enum MyEnum {
        E1,
        E2,
        E3
      }
    }
  }
}

I want to reference MyEnum in my Thymeleaf template. What I expect from the usual syntax is that this should work:

${T(com.my.packages.L1.L2.L3.MyEnum).E1}

However, this does not work and gives me the following error:

EL1005E: Type cannot be found (com.my.packages.L1.L2.L3.MyEnum)

To investigate I went step by step, checking whether I could reference any type like that at all. So, I simply tried to reference L1 first.

${T(com.my.packages.L1).E1}

This time I got an error telling me that L1 does not have a field E1. So the conclusion here is that Thymeleaf successfully referenced L2.

I tried the same thing with L2 and that "worked" as well. Same as with L1.

Then I tried L3 and Thymeleaf again failed to reference that type.

Does Thymeleaf have some sort of "maximum depth" when it comes to nested classes? Or do I need some alternative syntax in that case? Looking for this problem online is very difficult because every article I find simply shows me the above syntax, which works in principle, and doesn't consider nested classes.

I know I could probably just un-nest the classes and be done with it, but I'm not supposed to change the structure for other reasons, so that's a sub-optimal option.


Solution

  • When using nested classes you need to use $ as the separator and not the . notation. The . is for package while the $ is used for nested classes.

    If you would do a System.out.println(L1.L2.L3.MyEnum.class.getName()); The output would be something like the following

    your.package.L1$L2$L3$MyEnum
    

    To use the enum in an expression you have to follow the same naming pattern.

    ${T(com.my.packages.L1$L2$L3$MyEnum).E1} or ${T(com.my.packages.L1$L2$L3.MyEnum).E1} should do the trick.