Spring Boot Servlet API Version - spring

I'm trying to run a Spring Boot app on Tomcat 7. From my understanding, it should be compatible with servlet 3.0 spec.
In my dependency, I mark tomcat as provided:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope> <!-- Mark as provided so it doesn't interfere when we deploy in container -->
</dependency>
Edit: And I've added the property <tomcat.version>7.0.59</tomcat.version>
But I still can't start it in tomcat. I'm getting this error:
Caused by: java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;
at org.apache.tomcat.websocket.server.WsServerContainer.(WsServerContainer.java:147)
at org.apache.tomcat.websocket.server.WsSci.init(WsSci.java:131)
at org.apache.tomcat.websocket.server.WsSci.onStartup(WsSci.java:47)
Which are because it apparently needs servlet spec 3.1.
Am I missing something?

The problem is, spring-boot also configure websocket support on spring-boot-starter-tomcat, which is includes by spring-boot-starter-web. And according to Apache, you must use Java 7 if you want web socket with Tomcat 7.
Here: http://tomcat.apache.org/whichversion.html
Either compile with Java 7 or exclude websocket support
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
</exclusion>
</exclusions>
</dependency>

Related

change default web server on spring-boot 2.4.4

I'm working with Spring Boot 2.4.4 and I would change the default web server Tomcat to undertow orJHetty but I find it very difficult using both Gradle or Maven.
An old documentation exposes how do it but I'm sure all is changed because now tomcat, undertow and jetty configuration is embedded in the core library:
https://docs.spring.io/spring-boot/docs/2.1.9.RELEASE/reference/html/howto-embedded-web-servers.html
How do it in the 2.4.4 version?
There are no changes between the versions. This is well described right at the Spring Boot 2.4.4 Reference guide, right in 3.1. Use Another Web Server section. Basically, the change consists of two steps:
Exclude embedded Tomcat server dependency from the spring-boot-starter-web artifact:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- Exclude the Tomcat dependency -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
Include your embedded server as a separate dependency instead:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
Just don't forget to notice the following quote from the reference guide in the very same section which might or might not be relevant to you:
The version of the Servlet API has been overridden as, unlike Tomcat 9 and Undertow 2.0, Jetty 9.4 does not support Servlet 4.0.
follow three steps to change the default web server, change configuration in pom.xml.
1.exclude the default web server.
2.Include the necessary web server.
3.Maven update.
For example,
Instead of this
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
Add this one
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
for the necessary server add the appropriate web server dependency.

Autoconfiguation excluded but embedded servlet container is still being used

I've followed all the steps mentioned in the documentation to enable the traditional war deployment for spring boot app i.e excluded the EmbeddedServletContainerAutoConfiguration from the #EnableAutoConfiguration and I only have one such instance. Also extended SpringBootServletInitializer and make sure the packaged war doesnt have any tomcat starter dependency. Also ran the spring boot report and confirmed the EmbeddedServletContainerAutoConfiguration is in the exclusion list.
Apart from all the changes when I deploy the war it is still creating a embedded application context with embedded servlet contatiner.
What did I miss and what other areas can I inspect ? Spring boot version 1.5.13.
>
Hi Veeram,
We do not need to exclude the AutoConfiguration-classes, but excluding the tomcat dependency is needed.
You need to do is omit tomcat starter dependency from pom.xml. It gets pulled from spring-boot-starter-web as a transitive dependency. So, you need to add exclusion for it:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
Now, as you are using <packaging>war</packaging> and using SpringBootServletInitializer, we would need servlet-api dependency on the classpath.
So, add the servlet dependency to your pom.xml
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
Hope this helps!

ERROR:The type org.apache.log4j.Logger cannot be resolved. It is indirectly referenced from required .class files

Trying to upgrade a project from using Camel v2.21.2 to using Camel v2.22.0
This entails going from Spring v4.x to v5.x and from Spring-boot v1.5.x to Spring-boot v2.0.4.RELEASE.
Project uses groovy-all 2.4.15. We are not using log4j in our project, we are using slf4j-api(1.7.25) and logback(1.2.3) in our project. Yet, running a Maven install is giving an error saying that some class is using log4j
When I added log4j(1.2.17) dependency it is working fine but we don't want to add it.
Is there something that can be excluded from the spring-boot starter? Any other solutions? Any hints on how to diagnose the problem?
I think log4j or log4j2 should be in the classpath. Spring Boot v2.0.x has log4j2 added. If log4j2 is not compatible with Camel version. Exclude the log4j2 and add log4j dependency and try . Hope it should work..!
<!-- Exclude Spring Boot's Default Logging -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Add Log4j Dependency -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>

Spring Boot logging with Log4j2

Written simple POC to prove and test Spring Boot and log4j2 compatibility. Once successful I will move it to real application.
Please refer my POC source code:
https://github.com/Dennyss/SpringBootLog4j2POC
I know/read about Spring version and log4j2 compatibility from:
How to set up Spring Boot and log4j2 properly?
Found and tried recommendations described here:
Spring-Boot logging with log4j2?
But still not working. The problem is that both application logs and Spring logs are printing to console only.
Please refer maven dependencies below (from POC):
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
If I don't exclude Spring's logback and don't add boot-starter-log4j2 then application logs are printing to application file but Spring logs are not printing at all. I feel the problem somewhere with dependencies. Appreciate any help.
According to the Spring Boot Logging documentation, the location of the logging configuration file can be specified using the logging.config property. I noticed that your start.sh script is passing -Dlog4j.configurationFile. Normally, this would be sufficient for direct Log4J 2 integration, but Spring Boot uses logging.config.
After switching to this, it writes to the log files:
java -Dlogging.config=/share/LogPOC/log4j2.xml -cp poc.jar:libs/* com.poc.logger.Application

Log4J2 in Spring Boot with embedded Tomcat

I am trying to let the embedded Tomcat in Spring Boot log to my Log4J2 configuration, but it doesn't work.
According to this answer that copes with an external Tomcat: https://stackoverflow.com/a/28639068/1845463 there seems to be the need to move some jars to $Catalina_home/libs etc. I think this is not possible with Spring Boot, isn't it?
Has someone managed to get log4j2 running and be able to configure appenders for catalina log?
Thanks in advance
EDITED: The simplest way to do is to add spring-boot-starter-log4j2.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
N.B. Make sure that the other components don't need different version of log4j. This may cause run-time errors. e.g. elasticsearch java API requires 2.6+ and spring-boot-starter-log4j2:1.3.8 provides log4j:2.4.1, if we're building an app that connects elasticsearch and uses spring boot too. Then we will end up getting NoSuchMethodError or similar errors. For resolution of those errors we should add log4j2:2.6+ in our pom.
Which Spring Boot version are you using? I believe 1.4.x.RELEASE uplifted it to log4j2.
As #M.Deinum mentioned including:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
brings in:
log4j-core, log4j-api and a few more. See https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-log4j2/1.4.6.RELEASE
It might be advisable to exclude logging starter using:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>

Resources