Spring Boot - Configure Jetty Server

1. Introduction


In this article, You'll learn how to configure the jetty server in spring boot instead of the default tomcat server.

After creating a new spring boot application just start the application. That generates the following log and look at the last two lines that mentioning Tomcat Started on port 8080.

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.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.javaprogram</groupId>
<artifactId>spring-boot-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-app</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

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

</project>

Log:

If you are using a "spring-boot-starter-web" starter then it enables tomcat as an embedded server by default.

  .   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.6.RELEASE)

2020-04-15 17:40:27.898 INFO 28475 --- [ main] c.j.s.SpringBootAppApplication : Starting SpringBootAppApplication on -Pro-2.local with PID 28475 (/Users/venkateshn/Documents/VenkY/blog/workspace/spring-boot-app/target/classes started by venkateshn in /Users/venkateshn/Documents/VenkY/blog/workspace/spring-boot-app)
2020-04-15 17:40:27.901 INFO 28475 --- [ main] c.j.s.SpringBootAppApplication : No active profile set, falling back to default profiles: default
2020-04-15 17:40:29.070 INFO 28475 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-04-15 17:40:29.086 INFO 28475 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-04-15 17:40:29.086 INFO 28475 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.33]
2020-04-15 17:40:29.166 INFO 28475 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-04-15 17:40:29.166 INFO 28475 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1198 ms
2020-04-15 17:40:29.361 INFO 28475 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-04-15 17:40:29.570 INFO 28475 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-04-15 17:40:29.575 INFO 28475 --- [ main] c.j.s.SpringBootAppApplication : Started SpringBootAppApplication in 2.17 seconds (JVM running for 2.782)


2. Enable Jetty Server in Spring Boot


This is quite easy to enable the Jetty server by disabling the existing default tomcat server.

You need to exclude the tomcat from the web starter.


<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>


For now, the jetty server is not added yet. But let us start the application and see how the application is deployed.

  .   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.6.RELEASE)

2020-04-15 17:51:14.200 INFO 28944 --- [ main] c.j.s.SpringBootAppApplication : Starting SpringBootAppApplication on -Pro-2.local with PID 28944 (/Users/venkateshn/Documents/VenkY/blog/workspace/spring-boot-app/target/classes started by venkateshn in /Users/venkateshn/Documents/VenkY/blog/workspace/spring-boot-app)
2020-04-15 17:51:14.203 INFO 28944 --- [ main] c.j.s.SpringBootAppApplication : No active profile set, falling back to default profiles: default
2020-04-15 17:51:14.911 INFO 28944 --- [ main] c.j.s.SpringBootAppApplication : Started SpringBootAppApplication in 1.217 seconds (JVM running for 1.588)


From the log, It is saying the application is started but not deployed on any server. That is indicating that no server is attached to the application.

Adding jetty server into spring boot with the jetty starter as "spring-boot-starter-jetty" in pom.xml

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

If the server is started already on the same port 8080, it produces the following error.

Web server failed to start. Port 8080 was already in use.

Successful application startup log.

  .   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.6.RELEASE)

2020-04-15 17:54:59.287 INFO 29104 --- [ main] c.j.s.SpringBootAppApplication : Starting SpringBootAppApplication on -Pro-2.local with PID 29104 (/Users/venkateshn/Documents/VenkY/blog/workspace/spring-boot-app/target/classes started by venkateshn in /Users/venkateshn/Documents/VenkY/blog/workspace/spring-boot-app)
2020-04-15 17:54:59.291 INFO 29104 --- [ main] c.j.s.SpringBootAppApplication : No active profile set, falling back to default profiles: default
2020-04-15 17:55:00.603 INFO 29104 --- [ main] org.eclipse.jetty.util.log : Logging initialized @2514ms to org.eclipse.jetty.util.log.Slf4jLog
2020-04-15 17:55:00.785 INFO 29104 --- [ main] o.s.b.w.e.j.JettyServletWebServerFactory : Server initialized with port: 8080
2020-04-15 17:55:00.793 INFO 29104 --- [ main] org.eclipse.jetty.server.Server : jetty-9.4.27.v20200227; built: 2020-02-27T18:37:21.340Z; git: a304fd9f351f337e7c0e2a7c28878dd536149c6c; jvm 1.8.0_161-b12
2020-04-15 17:55:00.848 INFO 29104 --- [ main] o.e.j.s.h.ContextHandler.application : Initializing Spring embedded WebApplicationContext
2020-04-15 17:55:00.848 INFO 29104 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1440 ms
2020-04-15 17:55:01.031 INFO 29104 --- [ main] org.eclipse.jetty.server.session : DefaultSessionIdManager workerName=node0
2020-04-15 17:55:01.031 INFO 29104 --- [ main] org.eclipse.jetty.server.session : No SessionScavenger set, using defaults
2020-04-15 17:55:01.032 INFO 29104 --- [ main] org.eclipse.jetty.server.session : node0 Scavenging every 660000ms
2020-04-15 17:55:01.043 INFO 29104 --- [ main] o.e.jetty.server.handler.ContextHandler : Started o.s.b.w.e.j.JettyEmbeddedWebAppContext@42a9a63e{application,/,[file:///private/var/folders/g0/0x5m1w1950z18h3m6z6h1_000000gn/T/jetty-docbase.8312808006303778546.8080/],AVAILABLE}
2020-04-15 17:55:01.044 INFO 29104 --- [ main] org.eclipse.jetty.server.Server : Started @2957ms
2020-04-15 17:55:01.307 INFO 29104 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-04-15 17:55:01.684 INFO 29104 --- [ main] o.e.j.s.h.ContextHandler.application : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-04-15 17:55:01.684 INFO 29104 --- [ main] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-04-15 17:55:01.696 INFO 29104 --- [ main] o.s.web.servlet.DispatcherServlet : Completed initialization in 11 ms
2020-04-15 17:55:01.789 INFO 29104 --- [ main] o.e.jetty.server.AbstractConnector : Started ServerConnector@18f20260{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2020-04-15 17:55:01.791 INFO 29104 --- [ main] o.s.b.web.embedded.jetty.JettyWebServer : Jetty started on port(s) 8080 (http/1.1) with context path '/'
2020-04-15 17:55:01.797 INFO 29104 --- [ main] c.j.s.SpringBootAppApplication : Started SpringBootAppApplication in 3.194 seconds (JVM running for 3.71)


Now it is saying application on "Jetty started on port(s) 8080" and created instance for Jetty embed server using JettyEmbeddedWebAppContext.

3. Spring Boot Jetty Configurations


Spring Boot provides the configurations through application.properties file related to Jetty. You can customize which port jetty should be running and how many threads used.

And also many props are available to use. Even you can limit the post request size to a specific value.

The below all are pertaining to the jetty.

#Jetty Configurations

server.port=8082
server.servlet.context-path=/home
server.jetty.acceptors=1
#Number of acceptor threads to use. When the value is -1.

server.jetty.accesslog.append=false
# Append to log.

server.jetty.accesslog.date-format=dd/MMM/yyyy:HH:mm:ss Z
# Timestamp format of the request log.

server.jetty.accesslog.enabled=false
# Enable access log.

server.jetty.accesslog.extended-format=false
# Enable extended NCSA format.

server.jetty.accesslog.file-date-format=dd/MMM/yyyy
# Date format to place in a log filename.

server.jetty.accesslog.filename= app.log
# Log filename. If not specified, logs redirect to "System.err".

server.jetty.accesslog.locale=IN
# Locale of the request log.

server.jetty.accesslog.log-cookies=false
# Enable logging of the request cookies.

server.jetty.accesslog.log-latency=false
# Enable logging of request processing time.

server.jetty.accesslog.log-server=false
# Enable logging of the request hostname.

server.jetty.accesslog.retention-period=31
server.jetty.accesslog.time-zone=GMT
# Timezone of the request log.

#server.jetty.max-http-post-size=200000B # Maximum size of the HTTP post or put content.
# Number of selector threads to use. When the value is -1.
server.jetty.selectors=2

4. Configure Properties Through Bean JettyEmbeddedServletContainerFactory


All the above properties can be also configured from java code as well in Spring Boot 2.0 release.

import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;

@Bean
public ConfigurableServletWebServerFactory webServerFactory()
{
JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
factory.setPort(9009);
factory.setContextPath("/app");
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notfound.html"));
return factory;
}


Before Spring Boot 2.0

@Bean
public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() {
JettyEmbeddedServletContainerFactory jettyContainer =
new JettyEmbeddedServletContainerFactory();

jettyContainer.setPort(9002);
jettyContainer.setContextPath("/app");
return jettyContainer;
}

5. Jetty Start Up Errors


If you get any of these exceptions to the values mapped to the given property, Please provide the appropriate values.


***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to bind properties under 'server.jetty.acceptors' to java.lang.Integer:

Property: server.jetty.acceptors
Value: 1 # Number of acceptor threads to use. When the value is -1.
Origin: class path resource [application.properties]:5:24
Reason: failed to convert java.lang.String to java.lang.Integer

Action:

Update your application's configuration

I have also faced the same problem and resolved by providing valid values.

6. Conclusion


In this article, We've seen how to configure Jetty Server by adding jetty starter "spring-boot-starter-jetty". How to enable a certain property from application.properties file and java code.


As usual, the Code shown is present is over GitHub.

GitHub Code

0 Comments