problem-situation
1.
I have a extremely simple Controller
package com.redfrog.note;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class BallController {
@GetMapping("/p1")
public String p1() { return "main"; }
}
And this is the Folder structure
+---src
| +---main
| | +---java
| | | |
| | | \---com
| | | \---redfrog
| | | \---note
| | | BallController.java
| | | TestSpringHibernate1Application.java
| | |
| | \---resources
| | | application.properties
| | |
| | +---static
| | | index.html
| | |
| | \---templates
| | main.html
When I call http://127.0.0.1:8080/p1 it displays the content of main.html
-> good.
2.
Now I add in a module-info.java, & just do the exact same thing
-> error below is thrown::
(in Chrome)
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sun Apr 30 23:10:07 CST 2023
There was an unexpected error (type=Internal Server Error, status=500).
Error resolving template [main], template might not exist or might not be accessible by any of the configured Template Resolvers
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [main], template might not exist or might not be accessible by any of the configured Template Resolvers
at [email protected]/org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:869)
at [email protected]/org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:607)
at [email protected]/org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
at [email protected]/org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
at [email protected]/org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:366)
at [email protected]/org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:190)
at [email protected]/org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1406)
at [email protected]/org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1150)
at [email protected]/org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
at [email protected]/org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965)
at [email protected]/org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at [email protected]/org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at [email protected]/javax.servlet.http.HttpServlet.service(HttpServlet.java:529)
at [email protected]/org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at [email protected]/javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
at [email protected]/org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209)
at [email protected]/org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at [email protected]/org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at [email protected]/org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
at [email protected]/org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at [email protected]/org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at [email protected]/org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at [email protected]/org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
at [email protected]/org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at [email protected]/org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at [email protected]/org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at [email protected]/org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
at [email protected]/org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at [email protected]/org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at [email protected]/org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at [email protected]/org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
at [email protected]/org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
at [email protected]/org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at [email protected]/org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at [email protected]/org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
at [email protected]/org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
at [email protected]/org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at [email protected]/org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at [email protected]/org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at [email protected]/org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389)
at [email protected]/org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at [email protected]/org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)
at [email protected]/org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)
at [email protected]/org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at [email protected]/org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at [email protected]/org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at [email protected]/org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)
(in Postman, omitted some)
{
"timestamp": "2023-04-30T15:01:24.640+00:00",
"status": 500,
"error": "Internal Server Error",
"trace": "org.thymeleaf.exceptions.TemplateInputException: Error resolving template [main], template might not exist or might not be accessible by any of the configured Template Resolvers\r\n\tat [email protected]/org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:869)\r\n\tat
problem-question
How do I fix this?
I need to use module-info.java.
misc
I tried to look at the source code in debug mode.
Seems the code goes to return null; // << goes to here .
But I have no knowledge to dig deeper.
public abstract class AbstractTemplateResolver implements ITemplateResolver {
public final TemplateResolution resolveTemplate(
final IEngineConfiguration configuration,
final String ownerTemplate, final String template,
final Map<String, Object> templateResolutionAttributes) {
Validate.notNull(configuration, "Engine Configuration cannot be null");
// ownerTemplate CAN be null
Validate.notNull(template, "Template Name cannot be null");
// templateResolutionAttributes CAN be null
if (!computeResolvable(configuration, ownerTemplate, template, templateResolutionAttributes)) {
return null;
}
final ITemplateResource templateResource = computeTemplateResource(configuration, ownerTemplate, template, templateResolutionAttributes);
if (templateResource == null) {
return null;
}
if (this.checkExistence && !templateResource.exists()) { // will only check if flag set to true
return null; // << goes to here
}
return new TemplateResolution(
templateResource,
this.checkExistence,
computeTemplateMode(configuration, ownerTemplate, template, templateResolutionAttributes),
this.useDecoupledLogic,
computeValidity(configuration, ownerTemplate, template, templateResolutionAttributes));
}
more files
module-info.java
module sswwy {
exports com.redfrog.note;
opens com.redfrog.note;
requires java.base;
requires java.compiler;
requires java.datatransfer;
requires java.desktop;
requires java.instrument;
requires java.logging;
requires java.management;
requires java.management.rmi;
requires java.naming;
requires java.net.http;
requires java.prefs;
requires java.rmi;
requires java.scripting;
requires java.se;
requires java.security.jgss;
requires java.security.sasl;
requires java.smartcardio;
requires java.sql;
requires java.sql.rowset;
requires java.transaction.xa;
requires java.xml;
requires java.xml.crypto;
requires jdk.accessibility;
requires jdk.attach;
requires jdk.charsets;
requires jdk.compiler;
requires jdk.crypto.cryptoki;
requires jdk.crypto.ec;
requires jdk.crypto.mscapi;
requires jdk.dynalink;
requires jdk.editpad;
requires jdk.hotspot.agent;
requires jdk.httpserver;
requires jdk.internal.ed;
requires jdk.internal.jvmstat;
requires jdk.internal.le;
requires jdk.internal.opt;
requires jdk.internal.vm.ci;
requires jdk.internal.vm.compiler;
requires jdk.internal.vm.compiler.management;
requires jdk.jartool;
requires jdk.javadoc;
requires jdk.jcmd;
requires jdk.jconsole;
requires jdk.jdeps;
requires jdk.jdi;
requires jdk.jdwp.agent;
requires jdk.jfr;
requires jdk.jlink;
requires jdk.jpackage;
requires jdk.jshell;
requires jdk.jsobject;
requires jdk.jstatd;
requires jdk.localedata;
requires jdk.management;
requires jdk.management.agent;
requires jdk.management.jfr;
requires jdk.naming.dns;
requires jdk.naming.rmi;
requires jdk.net;
requires jdk.nio.mapmode;
requires jdk.random;
requires jdk.sctp;
requires jdk.security.auth;
requires jdk.security.jgss;
requires jdk.unsupported;
requires jdk.unsupported.desktop;
requires jdk.xml.dom;
requires jdk.zipfs;
// requires HikariCP;
// requires accessors.smart;
// requires android.json;
// requires antlr;
// requires assertj.core;
requires attoparser;
// requires com.fasterxml.classmate;
requires com.fasterxml.jackson.annotation;
// requires com.sun.istack.runtime;
// requires com.sun.xml.txw2;
// requires dom4j;
// requires jackson.core;
// requires jackson.databind;
// requires jackson.datatype.jdk8;
// requires jackson.datatype.jsr310;
// requires jackson.module.parameter.names;
// requires jakarta.activation;
requires java.annotation;
// requires java.persistence;
// requires java.transaction;
// requires java.xml.bind;
// requires json.path;
// requires json.smart;
// requires jsonassert;
requires jul.to.slf4j;
// requires log4j.api;
requires logback.classic;
requires logback.core;
// requires lombok;
// requires mysql.connector.j;
requires org.apache.logging.slf4j;
requires org.apache.tomcat.embed.core;
requires org.apache.tomcat.embed.el;
requires org.apache.tomcat.embed.websocket;
// requires org.apiguardian.api;
// requires org.aspectj.weaver;
// requires org.glassfish.jaxb.runtime;
// requires org.hamcrest;
// requires org.hibernate.commons.annotations;
// requires org.hibernate.orm.core;
// requires org.hibernate.orm.envers;
// requires org.jboss.jandex;
// requires org.jboss.logging;
// requires org.joda.time;
// requires org.junit.jupiter;
// requires org.junit.jupiter.api;
// requires org.junit.jupiter.engine;
// requires org.junit.jupiter.params;
// requires org.junit.platform.commons;
// requires org.junit.platform.engine;
// requires org.mockito;
// requires org.mockito.junit.jupiter;
// requires org.objectweb.asm;
// requires org.objenesis;
// requires org.opentest4j;
requires org.slf4j;
// requires org.xmlunit;
requires org.yaml.snakeyaml;
requires spring.aop;
// requires spring.aspects;
requires spring.beans;
requires spring.boot;
requires spring.boot.autoconfigure;
// requires spring.boot.devtools;
requires spring.boot.starter;
// requires spring.boot.starter.aop;
// requires spring.boot.starter.data.jpa;
// requires spring.boot.starter.jdbc;
requires spring.boot.starter.json;
requires spring.boot.starter.logging;
// requires spring.boot.starter.test;
requires spring.boot.starter.thymeleaf;
requires spring.boot.starter.tomcat;
requires spring.boot.starter.web;
// requires spring.boot.test;
// requires spring.boot.test.autoconfigure;
requires spring.context;
requires spring.core;
// requires spring.data.commons;
// requires spring.data.envers;
// requires spring.data.jpa;
requires spring.expression;
requires spring.jcl;
// requires spring.jdbc;
// requires spring.orm;
// requires spring.test;
// requires spring.tx;
requires spring.web;
requires spring.webmvc;
// requires testSpringHibernate;
requires thymeleaf;
requires thymeleaf.extras.java8time;
requires thymeleaf.spring5;
requires unbescape;
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.11</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.redfrog</groupId>
<artifactId>Test_SpringHibernate-1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Test_SpringHibernate-1</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
a complete folder structure (after added module-info.java)
| .classpath
| .gitignore
| .project
| HELP.md
| mvnw
| mvnw.cmd
| pom.xml
|
+---.mvn
| \---wrapper
| maven-wrapper.jar
| maven-wrapper.properties
|
+---.settings
| org.eclipse.core.resources.prefs
| org.eclipse.jdt.apt.core.prefs
| org.eclipse.jdt.core.prefs
| org.eclipse.m2e.core.prefs
| org.springframework.ide.eclipse.prefs
|
+---src
| +---main
| | +---java
| | | | module-info.java
| | | |
| | | \---com
| | | \---redfrog
| | | \---note
| | | BallController.java
| | | TestSpringHibernate1Application.java
| | |
| | \---resources
| | | application.properties
| | |
| | +---static
| | | index.html
| | |
| | \---templates
| | main.html
| |
| \---test
| \---java
| \---com
| \---redfrog
| \---note
\---target
+---classes
| | application.properties
| | module-info.class
| |
| +---com
| | \---redfrog
| | \---note
| | BallController.class
| | TestSpringHibernate1Application.class
| |
| +---META-INF
| | | MANIFEST.MF
| | |
| | \---maven
| | \---com.redfrog
| | \---Test_SpringHibernate-1
| | pom.properties
| | pom.xml
| |
| +---static
| | index.html
| |
| \---templates
| main.html
|
\---test-classes
\---com
\---redfrog
\---note
- (To avoid Exception throw due to any potential missing thing, I just
requiresnearly everything inmodule-info.java.)