19

I have an app that works perfectly when started within IntelliJ or via gradle bootRun.

however, if I do gradle bootRepackage and then try and run the resulting jar, I end up with:

2014-12-02 21:46:14.086 ERROR 9839 --- [nio-2014-exec-2] org.thymeleaf.TemplateEngine             : [THYMELEAF][http-nio-2014-exec-2] Exception processing template "/login": Error resolving template "/login", template might not exist or might not be accessible by any of the configured Template Resolvers
2014-12-02 21:46:14.087 ERROR 9839 --- [nio-2014-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/login", template might not exist or might not be accessible by any of the configured Template Resolvers] with root cause

org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/login", template might not exist or might not be accessible by any of the configured Template Resolvers
    at org.thymeleaf.TemplateRepository.getTemplate(TemplateRepository.java:245)
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1104)
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1060)
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1011)
    at org.thymeleaf.spring4.view.ThymeleafView.renderFragment(ThymeleafView.java:335)

I can see that the jar has /templates/** contained in it. the content looks OK to me.

One possible(?) factor may be that I use an html page referring to a layout, thus:

  layout:decorator="layouts/main"

I can confirm that the file IS in the jar.

/login is defined thusly:

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/login").setViewName("/login");
    registry.addViewController("/").setViewName("/login");
}

and I have spring security configured as:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
public void configure(WebSecurity security) {
    security.ignoring().antMatchers("/assets/**");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf().disable();
    http
            .authorizeRequests()
            .antMatchers("/").permitAll()
            .anyRequest().authenticated();
    http
            .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/home")
            .failureUrl("/login?error")
            .permitAll()
            .and()
            .logout()
            .invalidateHttpSession(true)
            .logoutSuccessUrl("/login?logout")
            .permitAll();
}
}

I think that's all that might be relevant to this issue...

I have seen https://github.com/spring-projects/spring-boot/issues/112 and Proper location of Thymeleaf views for Spring (amongst others). These resources notwithstanding, I have not been successful at getting template resolution working.

Any suggestions gratefully recieved.

To have come so far with Spring Boot yet to have stumbled at the last hurdle (near-final deployment) is vexatious.

Community
  • 1
  • 1
Bob Brown
  • 930
  • 2
  • 7
  • 14
  • Nothing obvious is jumping out at me and Spring Boot has a sample the uses Thymeleaf with a layout (https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-web-ui) so I don't think that's the problem. Perhaps looking at the sample could help spot a difference in your app's setup? – Andy Wilkinson Dec 02 '14 at 16:22

9 Answers9

15

I had same problem using spring boot with thymeleaf by default configuration. All worked until I have to try .jar

message says: ... org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/fragments/footer"

I solved playing with / , problem was that they don't need the slash.

I Changed this:

<footer class="footers" th:replace="/fragments/footer :: footer">

for this:

<footer class="footers" th:replace="fragments/footer :: footer">
user2822874
  • 159
  • 1
  • 4
  • 2
    I encounter the same error and was able to fix it because of your answer, so thank you. – blitzen12 Aug 01 '17 at 03:41
  • Not only this, but case sensitivity is an issue in some scenarios. Going from development to production (windows to linux) a fragment name had camel-case in a reference but itself was all lower case. One more thing to watch for. – J E Carter II Aug 04 '21 at 21:31
  • You saved my day. My problem is the String path returned by Controller involved a slash like `"/static/some.js"`, remove the slash worked fine for jar. – Wechar Yu Sep 08 '21 at 10:36
8

The answer seems to be here: https://github.com/spring-projects/spring-boot/issues/1744

In a nutshell: if a resouce path contains '//', things go awry.

The fix is to modify application.yml thusly:

spring:
  thymeleaf:
    prefix: classpath:/templates

(the fix is similar for a .properties file, of course)

The knock-on effect is that all references to templates or whatever need to be preceeded by a slash, as in (Thymeleaf .html file):

      layout:decorator="/layouts/main"

or (Groovy controller):

@RequestMapping(value = "/home", method = RequestMethod.GET)
def home(Model model, Principal principal) {

    "/home/home"
}

I think that spring boot should fix this. Urgently. This is REALLY bad ergonomics that blows up badly, just at the point where one feels like one is nearing final deployment.

Bob Brown
  • 930
  • 2
  • 7
  • 14
  • 3
    Thanks for posting this. What finally worked for me was to add the trailing slash to my property. `spring.thymeleaf.prefix=classpath:/templates/` – Derrek Mar 31 '16 at 16:15
  • 2
    Unfortunately this didnt fix for me, have exact same problem. Eclipse works, with executable jar cant resolve template ... :-( – Michael Hegner Mar 11 '17 at 20:07
  • I got the same issue "org.thymeleaf.exceptions.TemplateInputException: Error resolving template "ui/applications", template might not exist or might not be accessible by any of the configured Template Resolvers" when deploying spring boot admin in weblogic. I can login successfully, but the request "/admin/ui/applications" to get the list of services got the issue. I have tried adding the configuration above "spring.thymeleaf.prefix: classpath:/templates" but didn't work. Any configuration to resolve this? – Khoa Phung Jun 05 '19 at 07:03
6

Okay, I found where you have to take a close look. In your Controller classes, when you use @RequestMapping on class, no leading slash (e.g. @RequestMapping("property")). On Method you need a leading slash (e.g. @GetMapping("/list")) and the return value no leading slash (e.g. return "property/list";)

An Example Snippet

@Controller
@RequestMapping("property")
public class PropertyController {
    @NonNull PropertyService service;

    @GetMapping("/list")
    public String list() {
        return "property/list";
    }
}
Michael Hegner
  • 5,555
  • 9
  • 38
  • 64
2

I faced the issue when using the spring-boot-starter-thymeleaf dependency

So I have used the below dependency instead,

        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf</artifactId>
            <version>3.0.9.RELEASE</version>
        </dependency>
firstpostcommenter
  • 2,328
  • 4
  • 30
  • 59
1

If the above solutions don't work for you, like me,

I changed my Controller to a RestController. It fixed my issue.

This is, if you are using a Front End App like Angular to talk to your Back-end application.

  • Welcome to SO, please describe your answer with more detail like bring some code sample, then users can understand your answer better – Saeed Zhiany Sep 22 '19 at 05:08
1

For me there was nothing wrong with my code. All I did was run the mvn clean command in my terminal then restart the app again and it worked fine.

CanCoder
  • 1,073
  • 14
  • 20
  • This was published as an answer, but does not attempt to answer the question. Possibly it should be a comment – borchvm May 07 '20 at 08:08
1

This issue is with @Restcontroller because @RestController annotation is mix of @responseBody and @controller annotation

RestController default response body is json or string format what ever string html name is added its consider as string then its display string in the default html

change @restController to @ controller then it will work

shashigura
  • 133
  • 1
  • 2
  • 8
0

spring.thymeleaf.prefix=classpath:/templates/

change

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/login").setViewName("/login");
    registry.addViewController("/").setViewName("/login");
}

to

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/login").setViewName("login");
    registry.addViewController("/").setViewName("login");
}

the view name should be Relative path

s332401890
  • 121
  • 2
  • 8
0

After many of tentatives I found a way to resolve my problem about the template error. I dont know if is related to the new version of spring-boot but my change worked.

Every request throught controller instead of returning String "/login", for example, I change to create a object ModelAndView:

@RequestMapping(value="/login", method=RequestMethod.GET)
public ModelAndView login() {
    ModelAndView mv = new ModelAndView("login");
    return mv;
}

hugs to all.