hawkbit-dmf-server 1.1.0 does not start: NoClassDefFoundError jakarta/servlet/ServletResponse
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 77/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- docker, java, spring-boot
Direzione di ricerca
Inizia da hawkbit-dmf/hawkbit-dmf-server/pom.xml e confronta la sua dipendenza dalla Servlet API con la versione 1.0.4. Compila il server DMF con mvn -pl hawkbit-dmf/hawkbit-dmf-server -am package, quindi esegui il JAR generato con il profilo H2. Il lavoro è completato quando il servizio si avvia senza il NoClassDefFoundError di jakarta.servlet.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
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.
- Lingua principale
- Java
- Stelle
- 601
- Fork
- 228
- Merge medio
- 18h 20m
- PR unite (30g)
- 58
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di eclipse-hawkbit/hawkbit
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 42/100
eclipse-hawkbit/hawkbit#3266 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Configurable automatic retries for failed actions (policy, backoff, rollout and auto-assignment support)Forse di nuovo libera @strailov l’ha presa 75 giorni fa e non c’è nessuna pull request aperta. Apertafeature request
eclipse-hawkbit/hawkbit#3251 · 3 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
IN_SYNC and rollout success can be recorded while the device still runs the old imageForse di nuovo libera @denislavprinov l’ha presa 107 giorni fa e non c’è nessuna pull request aperta. Aperta
eclipse-hawkbit/hawkbit#3185 · 1 reazione · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
doumentation: openapi.json is not updated after recent Hawkbit releasesForse di nuovo libera @denislavprinov l’ha presa 72 giorni fa e non c’è nessuna pull request aperta. Aperta
eclipse-hawkbit/hawkbit#3035 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
eclipse-hawkbit/hawkbit#3010 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di eclipse-hawkbit/hawkbit
Issue simili
-
bug/错误
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
FCL-Team/FoldCraftLauncher#1951 ·
I maintainer di solito rispondono entro 4 giorni
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 68/100
quarkusio/quarkus-agent-mcp#296 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
commons-app/apps-android-commons#7072 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement web-ui
Difficoltà 2/5 1-3 ore Idoneità per principianti 67/100
jenkinsci/jenkins#27583 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100