Skip to content

Zipkin Server with Spring Boot: Why You Should Exclude Tomcat and How to Configure It

Purpose

This post demonstrates how to properly configure a standalone Zipkin server using Spring Boot. The key insight is that Zipkin server uses Armeria as its embedded server, not Tomcat, so you must exclude Tomcat from your dependencies.

Environment

  • Spring Boot 2.2.4
  • Spring Cloud Hoxton.SR1
  • Zipkin 2.19.9
  • Java 8+

The Architecture Difference

Regular Spring Boot web applications use Tomcat as the default embedded server:

Spring Boot web architecture
┌─────────────────────────────────────┐
│ Spring Boot Web Application │
│ ┌─────────────────────────────┐ │
│ │ Tomcat Embedded Server │ │
│ │ - Handles HTTP requests │ │
│ │ - Standard servlet context │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘

Zipkin server uses Armeria instead:

Zipkin server architecture
┌─────────────────────────────────────┐
│ Zipkin Server Application │
│ ┌─────────────────────────────┐ │
│ │ Armeria Embedded Server │ │
│ │ - High performance │ │
│ │ - Custom protocol support │ │
│ │ - Non-blocking I/O │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘

Armeria is a microservice-friendly HTTP/RPC server and client library. Zipkin needs it for performance when handling high-volume trace data.

The Configuration

Here’s the complete working configuration:

pom.xml
<dependencies>
<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>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
</dependency>
</dependencies>
ZipkinServerApplication.java
@EnableZipkinServer
@SpringBootApplication
public class ZipkinServerApplication {
public static void main(String[] args) {
SpringApplication.run(ZipkinServerApplication.class, args);
}
}

How It Works

When I run this:

Start Zipkin server
mvn spring-boot:run

I get this output:

Successful startup
Started ZipkinServerApplication in 3.5 seconds
Zipkin UI available at http://localhost:9411

The exclusion allows Zipkin to use Armeria without Tomcat interference. The @EnableZipkinServer annotation creates the Zipkin-specific server context and registers the necessary endpoints for trace collection.

Why the Exclusion Matters

Without the Tomcat exclusion, you’ll see bean creation errors:

Error without exclusion
Error creating bean with name 'webMvcMetricsFilter'
nested exception: java.lang.NoClassDefFoundError: zipkin2/internal/Buffer$Writer

This happens because:

  1. Tomcat initializes with Spring Boot’s standard servlet context
  2. Zipkin’s Armeria server creates a different context
  3. Actuator metrics (webMvcMetricsFilter) expect the Tomcat context
  4. Zipkin classes conflict with the metrics initialization

Alternative: Use Zipkin Server Standalone

You can also run Zipkin server without Spring Boot web starter entirely:

Alternative configuration (minimal)
<dependencies>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
</dependency>
</dependencies>

This is cleaner if you only need Zipkin server and no other Spring Boot web features.

Summary

In this post, I showed how to configure a Zipkin server with Spring Boot. The key point is to exclude Tomcat from spring-boot-starter-web because Zipkin uses Armeria as its embedded server. Without this exclusion, the two servers conflict and cause bean creation errors.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments