Spring boot not finding template when deployed on docker - spring

My app works just fine if I run the application on my host using the
mvn spring-boot:run
but when I deploy it on docker, it does not work and I get this error:
SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/store/index", 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 "/store/index", template might not exist or might not be accessible by any of the configured Template Resolvers
but if I go on the url: http:localhost:8080/login which is controlled by spring security, renders the template normally. Seems to be a permission problem but I'm not sure.
here is my Dockerfile:
FROM openjdk
VOLUME /tmp
RUN touch engdevcommerce.jar
COPY target/engdevcommerce.jar engdevcommerce.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/engdevcommerce.jar"]
Solution:
Turns out the problem I was having, had nothing to do with the docker deployment. I ran the jar file on my host, and I was getting the same error.
The problem was that, where I returned the view url at the controllers methods, I was starting with slash like this: "/.../..." . And spring does not load view with double slash when the application is packed as .jar file. I had to remove the slash character at the beginning of the url every where I returned a ModelAndView and at the th:insert tags too on my html files.
this link helped me a lot :
spring-boot-thymeleaf-not-resolving-fragments-after-packaging

Always check the application execution first with 'java -jar your_app_name.jar' command!
In general this issue is mostly resolved by checking following 3 points-
Your application.properties should have the entry-
spring.thymeleaf.prefix=classpath:/templates/
Your controller should return name of the template without any preceding slash. As the thymeleaf configuration is case sensitive.
Your Project should follow standard spring boot thymeleaf directory structure. If not, then make changes accordingly in your application.properties file.

add your local index directory to dockerfile so it will create /store and copy the index directory to /store then your docker vm will have /store/index with the contents from you local index directory
...
...
ADD <local-index-directory> /store
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-
jar","/engdevcommerce.jar"]

Related

how can i set was: SpringBoot(tomcat) + web: nginx(bring the thymeleaf resource files from was) on docker in linux

It was a project with a base of springboot + thymeleaf.
I want to use the web server by using nginx to place the resource files of thymeleaf on the web server.
Running nginx and spring boot project (WAS) with docker container.
nginx uses a port number of 8003:80 and WAS 8002:8080.
At this time, I want to know the settings of nginx.conf and the settings of the application.yml file of WAS.
In the linux environment, there is a situation where mapping is not working properly depending on whether or not thymeleaf is "/", so I want to solve this.
The settings for nginx.conf are as follows.
server {
listen 80;
location / {
proxy_pass http://ipaddr:8002;
...
}
location /templates {
root /usr/resources/templates;
}
location /css/ {
alias /usr/resources/static;
}
}
The application.yml setting for WAS is as follows.
thymeleaf:
prefix: /usr/resources/templates/
suffix: .html
Some are omitted, but by default, they refer to the directory in the same way as above.
When you run each server, the was server and nginx seem to be calling normally, but they don't seem to map the screen that will eventually be displayed properly.
[TemplatesInputException: Error resolving template [common/pagename], template might not exist or might not be accessible by any of the configured Template Resolves]
An error is occurring. Please Help me.
I tried to modify the nginx.conf file in nginx and the application.yml file in was server in many ways.

Spring application war - Google App Engine - How to specify Log location, profile, environment variab;les

I have a spring boot application bundled as war file , and able to push to App Engine
But I am getting problems starting app (I suspect there could be an issue with DB too...but couldnt remember where I saw...a nightmare)
java.lang.RuntimeException: java.lang.IllegalStateException: Logback
configuration error detected: ERROR in
ch.qos.logback.core.rolling.RollingFileAppender[FILE] - Failed to
create parent directories for
[/base/data/home/apps/e~pemy/20210716t001812.436581063072799646/logs/pynew.log]
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[FILE] -
openFile(logs/pynew.log,true) call failed.
java.io.FileNotFoundException: logs/pynew.log (No such file or
directory)
I am using the below properties in my application props
> logging.file.path=logs
> logging.file.name=${logging.file.path}/pynew.log
I am finding it very hard to include google specific dependencies and properties , and making a mess of my project...created app.yaml, web-inf>> appengine-web xml, logging.properties (not sure why but added as told in a tutorial)
Question: How can I create parent directory or link to cloud storage folder etc?
I also want to specify a profile and I see I can do it in yaml file. Is this used only
env_variables:
JAVA_USER_OPTS: '-Dspring.profiles.active=prod'
But I would like to know how to connect to Cloud SQL
spring.datasource.url=jdbc:mysql:///mydb?cloudSqlInstance=myapp:europe-west2:dBinstancename&socketFactory=com.google.cloud.sql.mysql.SocketFactory
spring.datasource.username=${dbuser}
spring.datasource.password=ENC(${dbencpwd})
spring.cloud.gcp.sql.database-name=mydb
spring.cloud.gcp.sql.instance-connection-name=myapp:europe-west2:dBinstancename
It is so confusing that I keep forgetting which connection needs password and which wont. and keep breaking my local
Question
Assuming that I need to supply credentials, How can I supply - ${dbuser}
I used the default spring logger with logback-spring.xml for all my development, and this is not working on AppEngine
So I followed https://cloud.google.com/logging/docs/setup/java
and added logback.xml and the dependency
implementation 'com.google.cloud:google-cloud-logging-logback:0.121.3-alpha'

Camel validate against file from classpath

I want to validate xml against schema - using SpringBoot 2 and camel 3.
On localhost this works:
.to("validator:file:src/main/resources/D.xsd")
But when uploaded to server on tomcat machine with context for example D - i get an error:
Caused by: java.io.FileNotFoundException: src/main/resources/D.xsd (No such file or directory)
I think that i need to change the path to use classpath - but i am not sure how to make it work ?
What i tried:
.to("validator:file:classpath:/src/main/resources/D.xsd")
.to("validator:file:resource:classpath:src/main/resources/D.xsd")
.to("validator:file:resource:classpath:/src/main/resources/D.xsd")
But it does not work.
In one of my applications (but with SpringBoot 1.5 and Camel 2.x) this works fine
.to("validator:classpath:folder/filename.xsd")
to validate against filename.xsd that is located in src/main/resources/folder
I've managed to fix it with:
.to("validator:D.xsd")

How do I load ${catalina.home}/conf/application.properties in a Spring / Tomcat webapp?

How do I load ${catalina.home}/conf/application.properties in a Spring / Tomcat webapp?
Looking around on StackOverflow and Google I see many discussions which claim it's possible. However, it's just not working for me. In line with the advice from my research my Spring applicationContext.xml file contains the following line:
<context:property-placeholder location="${catalina.home}/conf/application.properties"/>
But I get this in the logs:
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/Users/username/Servers/apache-tomcat-6.0.36/conf/application.properties]
From the log entry I can see that ${catalina.home} is expanding correctly. When I expand it by hand in the applicationContext.xml file it returns the same error. The following returns the contents of the application.properties file as expected:
cat /Users/username/Servers/apache-tomcat-6.0.36/conf/application.properties
So the path is clearly correct. Is this a webapp security or Tomcat server configuration issue?
The location of a context:property-placeholder is a Resource, which means that if you provide just a file path (as opposed to a full URL with a protocol) then the path will be resolved against the base directory of the webapp - it is trying to load /Users/username/Servers/apache-tomcat-6.0.36/webapps/<appname>/Users/username/Servers/apache-tomcat-6.0.36/conf/application.properties, which does not exist. If you prefix it with file: it'll work as you require:
<context:property-placeholder location="file:${catalina.home}/conf/application.properties"/>
For annotation based configuration you can use:
#PropertySource("file:${catalina.home}/conf/application.properties")

jboss/tomcat tld cache invalidation

I have a jboss application with some ears. There's war inside ear and there's file monitor.tld inside WEB-INF folder of war.
There's some tag definitions inside the monitor.tld. I added my custom tag definition in this file, and restarted jsboss. After that, when I use my tag in jsp I get error:
2011-04-23 16:38:31,829 INFO [STDOUT] 2011-04-23 16:38:31,761 [http-0.0.0.0-8080-4] ERROR [] org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/Monitor].[jsp] - Servlet.service() for servlet jsp threw exception
org.apache.jasper.JasperException: /tiles/layout/wizardLayout.jsp(140,4) No tag "wizardNavEx" defined in tag library imported with prefix "mon"
at org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40)
at org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407)
at org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:198)
at org.apache.jasper.compiler.Parser.parseCustomTag(Parser.java:1213)
at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1449)
at org.apache.jasper.compiler.Parser.parse(Parser.java:133)
at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:216)
at org.apache.jasper.compiler.ParserController.parse(ParserController.java:103)
at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:167)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:306)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:286)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:273)
at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:566)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:316)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:336)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:654)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:445)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:379)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:292)
at org.apache.struts.action.RequestProcessor.doForward(RequestProcessor.java:1078)
at org.apache.struts.tiles.TilesRequestProcessor.doForward(TilesRequestProcessor.java:295)
at org.apache.struts.tiles.TilesRequestProcessor.processTilesDefinition(TilesRequestProcessor.java:271)
at org.apache.struts.tiles.TilesRequestProcessor.processForwardConfig(TilesRequestProcessor.java:332)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:232)
...
So, my custom tag wizardNavEx doesn't work, but wizardNav defined in monitor.tld a couple of lines above works fine.
I think the problem is tomcat/jboss cached previous version of monitor.tld in someplace. How can I clear that caches? Any ideas?
Versions:
X-Powered-By='Servlet 2.4; JBoss-4.2.2.GA (build: SVNTag=JBoss_4_2_2_GA date=200710221139)/Tomcat-5.5'
The problem was that another monitor.tld existed inside one of jar files.

Resources