hawkbit-dmf-server 1.1.0 does not start: NoClassDefFoundError jakarta/servlet/ServletResponse
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 77/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- docker, java, spring-boot
Research direction
Start with hawkbit-dmf/hawkbit-dmf-server/pom.xml and compare its servlet API dependency with the 1.0.4 version. Build the DMF server with mvn -pl hawkbit-dmf/hawkbit-dmf-server -am package, then run the packaged jar with the H2 profile. Done when the service starts without the jakarta.servlet NoClassDefFoundError.
Written by the indexing model from the issue text.
Description
Summary
hawkbit/hawkbit-dmf-server:1.1.0 does not start. The Spring context fails while it creates the authenticationSuccessHandler bean of SecurityAutoConfiguration, with java.lang.NoClassDefFoundError: jakarta/servlet/ServletResponse, and the process exits with code 1. 1.0.4 starts with the same setup.
It happens with the image defaults (H2, no broker) and with docker/mysql/docker-compose-micro-services-mysql.yml of the 1.1.0 tag, where the hawkbit-dmf container restarts in a loop. A build of the current master (bf5812735) fails in the same way.
Steps to reproduce
docker run --rm hawkbit/hawkbit-dmf-server:1.1.0- The container exits after a few seconds with code 1. No database, broker or configuration is needed for this; the image defaults to
PROFILES=h2.
The script below runs 1.0.4 as control and then 1.1.0, and it shows whether jakarta.servlet-api is in BOOT-INF/lib. It needs only docker and removes its container on exit.
repro.sh
#!/usr/bin/env bash
# hawkbit-dmf-server 1.1.0 does not start: NoClassDefFoundError for
# jakarta/servlet/ServletResponse.
#
# Usage: repro.sh [image ...]
# default images: hawkbit/hawkbit-dmf-server:1.0.4 (control) and :1.1.0
#
# Each image runs with its defaults (PROFILES=h2, no database, no broker,
# no configuration). The script waits up to 90 s for "Started DmfStart" or
# for the container to exit, prints the result, the first error lines and
# whether jakarta.servlet-api is in BOOT-INF/lib. Needs docker only; the
# containers are removed on exit.
set -euo pipefail
IMAGES=("$@")
[ ${#IMAGES[@]} -gt 0 ] || IMAGES=(hawkbit/hawkbit-dmf-server:1.0.4 hawkbit/hawkbit-dmf-server:1.1.0)
NAME=dmf-repro
cleanup() { docker rm -f "$NAME" >/dev/null 2>&1 || true; }
trap cleanup EXIT
for image in "${IMAGES[@]}"; do
cleanup
docker pull -q "$image" >/dev/null
echo "== $image ($(docker image inspect -f '{{.Id}}' "$image" | cut -c8-19))"
docker run -d --name "$NAME" "$image" >/dev/null
result="no result after 90 s"
for _ in $(seq 90); do
if docker logs "$NAME" 2>&1 | grep -q 'Started DmfStart'; then
result="started: $(docker logs "$NAME" 2>&1 | grep -o 'Started DmfStart in [0-9.]* seconds')"
break
fi
if [ "$(docker inspect -f '{{.State.Status}}' "$NAME")" = exited ]; then
result="exited with code $(docker inspect -f '{{.State.ExitCode}}' "$NAME")"
break
fi
sleep 1
done
echo "result: $result"
docker logs "$NAME" 2>&1 | grep -E '^(Caused by|org\.springframework\.beans\.factory\.BeanCreationException)' |
awk 'length > 240 { s = substr($0, 1, 240); sub(/ [^ ]*$/, "", s); $0 = s " …" } 1' | head -4
echo "servlet API in BOOT-INF/lib: $(docker run --rm --entrypoint sh "$image" -c \
'ls /app/BOOT-INF/lib | grep -i "^jakarta.servlet-api" || echo none')"
echo
done
./repro.sh uses 1.0.4 and 1.1.0; other images can be passed as arguments.
Measured
2026-10-21, Docker Engine 29.9.1. The images run Java 21.0.11 (Temurin); the master build ran on maven:3.9-eclipse-temurin-21. The transcripts are in the comment.
| Run | Result | jakarta.servlet-api in BOOT-INF/lib |
|---|---|---|
hawkbit-dmf-server:1.0.4 (sha256:353c2cb0ce2f) |
Started DmfStart in 6.129 seconds |
jakarta.servlet-api-6.0.0.jar |
hawkbit-dmf-server:1.1.0 (sha256:66e18cb15068) |
exit 1, NoClassDefFoundError: jakarta/servlet/ServletResponse |
none |
master bf5812735, mvn -pl hawkbit-dmf/hawkbit-dmf-server -am package, then java -Dspring.profiles.active=h2 -jar |
exit 1, same error | none |
| the same master build with the dependency from "Possible direction" | Started DmfStart in 5.41 seconds |
jakarta.servlet-api-6.1.0.jar |
docker/mysql/docker-compose-micro-services-mysql.yml of the 1.1.0 tag (images pinned to 1.1.0, host ports removed) |
hawkbit-dmf restarted 9 times in 2 minutes with the same error; mgmt and ddi run |
not checked |
Where
SecurityAutoConfiguration (hawkbit-autoconfigure) creates three beans from Spring Security's servlet classes: authenticationSuccessHandler() returns a SimpleUrlAuthenticationSuccessHandler, logoutHandler() a SecurityContextLogoutHandler and logoutSuccessHandler() a SimpleUrlLogoutSuccessHandler. These classes come from spring-security-web (declared in hawkbit-dmf-amqp) and refer to jakarta.servlet types. The DMF server runs with spring.main.web-application-type=none, but the auto-configuration is applied anyway and creates the beans.
Up to 1.0.4, hawkbit-dmf/hawkbit-dmf-server/pom.xml declared jakarta.servlet:jakarta.servlet-api in compile scope. Commit 1be473b22 ("[#2845] Bump Spring boot to 4.x (#2941)") removed this declaration. The same commit also removed the provided declaration in hawkbit-autoconfigure and the test one in hawkbit-core, but these never reached the DMF jar, so the declaration in the DMF server was the one that counted. Since then nothing brings the servlet API onto the classpath of this module: the 1.0.4 image has jakarta.servlet-api-6.0.0.jar, the 1.1.0 image has none.
Possible direction
-
Restore the dependency in
hawkbit-dmf/hawkbit-dmf-server/pom.xml, as it was in 1.0.4. With this change the master build starts (see the table):<dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> </dependency> -
Or create the servlet-bound beans only in a servlet web application, for example with
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)on the three methods, so a non-web service does not need the servlet API at all. We did not test this variant.
References
- Removal of the dependency: https://github.com/eclipse-hawkbit/hawkbit/commit/1be473b22c50e913aeb2d24e29e66a93b98c21cf
SecurityAutoConfigurationon master: https://github.com/eclipse-hawkbit/hawkbit/blob/bf5812735d729b463aad45f9ec9c0089a42daefa/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java- Compose file used for the last row: https://github.com/eclipse-hawkbit/hawkbit/blob/1.1.0/docker/mysql/docker-compose-micro-services-mysql.yml
Thanks for having a look.
- Dominant language
- Java
- Stars
- 601
- Forks
- 228
- Avg merge
- 15h 58m
- Merged PRs (30d)
- 62
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from eclipse-hawkbit/hawkbit
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
eclipse-hawkbit/hawkbit#3436 ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 42/100
eclipse-hawkbit/hawkbit#3266 · 2 comments ·
Maintainers usually reply within 1 day
-
Configurable automatic retries for failed actions (policy, backoff, rollout and auto-assignment support)May be free again @strailov claimed this 77 days ago, and no pull request is open. Openfeature request
eclipse-hawkbit/hawkbit#3251 · 3 comments · 1 assignee ·
Maintainers usually reply within 1 day
-
IN_SYNC and rollout success can be recorded while the device still runs the old imageMay be free again @denislavprinov claimed this 108 days ago, and no pull request is open. Open
eclipse-hawkbit/hawkbit#3185 · 1 reaction · 1 assignee ·
Maintainers usually reply within 1 day
-
doumentation: openapi.json is not updated after recent Hawkbit releasesMay be free again @denislavprinov claimed this 74 days ago, and no pull request is open. Open
eclipse-hawkbit/hawkbit#3035 · 1 assignee ·
Maintainers usually reply within 1 day
All issues in eclipse-hawkbit/hawkbit
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
2026 Error Report
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
triplea-game/triplea#15096 ·
Maintainers usually reply within 1 day
-
[Bug][API] Switching workflow versions leaves schedules onlinePossibly taken @zhuangchong claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
apache/dolphinscheduler#18731 ·
Maintainers usually reply within 1 day
-
Implement JDBC Domain Enums (`SqlCategory`, `SqlExecutionStatus`, `SqlExecutionType`) in Core ModuleOpencore-module enhancement good first issue
Difficulty 1/5 1-3 hours Newbie friendliness 87/100
sdlc-pro/spring-lens#531 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
apache/rocketmq-dashboard#7340 ·
Maintainers usually reply within 3 days