Search code examples
mavenspring-bootcommand-linejarthymeleaf

Cannot access templates running Spring Boot with JAR


I have to run a Spring Boot on the command line using its JAR. I've seen already many topics about the "fat JAR", which I believe I have already created.

The program uses Spring Boot + Maven + Thymeleaf + Spring Security.

The problem

  • Templates that are in the templates folder - i.e. /resources/templates/<file> are displayed correctly (I have index.html, login.html and underConstruction.html tested and working)
  • Templates that are in subfolders - i.e. /resources/templates/client/edit.html or /resources/templates/client/search.html - fail to render with the following error shown on the browser

There was an unexpected error (type=Internal Server Error, status=500). Error resolving template "/client/add", template might not exist or might not be accessible by any of the configured Template Resolvers

Changing Spring Security config to permit all requests on a given URL doesn't change anything, so I think it's not related to it.

Running the app

  1. Using Maven: ./mvnw spring-boot:run works fine
  2. Using the JAR: java -jar myApp-0.0.1-SNAPSHOT0.jar start correctly, but doesn't render the pages mentioned above

Building the JAR

  • Executed ./mvnw clean package or ./mvnw clean install

There are 2 JAR files generated

  1. myApp-0.0.1-SNAPSHOT.jar with size of 42MB
  2. myApp-0.0.1-SNAPSHOT.jar.original with size of 684K

The pom.xml file (just a small snippet to show the plugin that generates the "fat JAR")

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

A random Controller (just to have an idea of how their code is)

@Controller
public class ClientController {

    @RequestMapping(path = "/client/search", method = RequestMethod.GET)
    public String search(Model model) {
        model.addAttribute("client", new Client());
        model.addAttribute("clients", new ArrayList<Client>());

        return "/client/search";
    }

    @RequestMapping(path = "/client/add", method = RequestMethod.GET)
    public String edit(Model model) {
        model.addAttribute("client", new Client());
        return "/client/edit";
    }
}

Any suggestion is very welcome.


Solution

  • Your issue is likely how you are returning the template names:

    @Controller
    public class ClientController {
    
        //and you could just make this simpler, like:
        //@GetMapping("/search")
        @RequestMapping(path = "/client/search", method = RequestMethod.GET)
        public String search(Model model) {
            model.addAttribute("client", new Client());
            model.addAttribute("clients", new ArrayList<Client>());
    
            return "client/search"; //NOTE: no slash
        }
    
        @RequestMapping(path = "/client/add", method = RequestMethod.GET)
        public String edit(Model model) {
            model.addAttribute("client", new Client());
            return "client/edit"; //NOTE: no slash
        }
    }