Incomplete Jackson 2 classpath breaks Grails 8 startup with NoClassDefFoundError in DefaultHttpMessageConverters
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 45/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Tranquilla
- Stack tecnologico
- groovy, spring-boot
- Ambito
- backend, build-system
Direzione di ricerca
Inizia riproducendo il problema con la dipendenza grails-elasticsearch, quindi analizza dependencyInsight e il contenuto di BOOT-INF/lib prodotto da bootJar. Leggi l’elemento dello stack DefaultHttpMessageConverters.detectMessageConverters e confronta gli artefatti Jackson 2 e Jackson 3. Il lavoro è completato quando l’applicazione si avvia senza NoClassDefFoundError, mantenendo il comportamento previsto delle dipendenze Jackson.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
A Grails 8 web application fails to start with NoClassDefFoundError: com/fasterxml/jackson/databind/exc/InvalidDefinitionException as soon as any dependency puts Jackson 2 jackson-core / jackson-annotations on the runtime classpath without Jackson 2 jackson-databind.
Grails 8 ships Jackson 3 for databind (tools.jackson), but the managed platform still supplies Jackson 2 jackson-core, jackson-annotations, and the Jackson 2 dataformat artifacts. When a plugin or library pulls in Jackson 2 core, the resulting classpath has "half of Jackson 2": Spring Framework 7's DefaultHttpMessageConverters.detectMessageConverters() concludes Jackson 2 is available and then hard-references a jackson-databind 2.x class that is not present.
The failure happens while creating OrderedFormContentFilter, so Tomcat never starts and the whole application is dead, regardless of whether the app itself uses Jackson at all.
Found while testing released Grails 7 plugins against 8.0.0-M5.
Grails Version
8.0.0-M5
Java / Groovy Version
Java 21.0.11 (Corretto), Groovy 5.0.8, Spring Boot 4.1.0, Spring Framework 7.0.8
Steps to Reproduce
- Generate a stock web app with the published 8.0.0-M5 distribution:
grails create-app elasticsearch --profile=web
- Add a single dependency that transitively brings Jackson 2 core. Any such dependency reproduces it; the one used here is a released Grails 7 plugin:
implementation "org.grails.plugins:grails-elasticsearch:5.1.0"
- Run
gradlew test integrationTest bootJar, or simply boot the app.
Actual Behaviour
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate
[org.springframework.boot.servlet.filter.OrderedFormContentFilter]:
Factory method 'formContentFilter' threw exception with message:
com/fasterxml/jackson/databind/exc/InvalidDefinitionException
Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/exc/InvalidDefinitionException
at org.springframework.http.converter.DefaultHttpMessageConverters$DefaultBuilder.detectMessageConverters(DefaultHttpMessageConverters.java:334)
at org.springframework.http.converter.DefaultHttpMessageConverters$DefaultClientBuilder.build(DefaultHttpMessageConverters.java:468)
at org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter.<init>(AllEncompassingFormHttpMessageConverter.java:42)
at org.springframework.web.filter.FormContentFilter.<init>(FormContentFilter.java:61)
at org.springframework.boot.servlet.filter.OrderedFormContentFilter.<init>(OrderedFormContentFilter.java:29)
at org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration.formContentFilter(WebMvcAutoConfiguration.java:189)
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException
Wrapped in WebServerException from TomcatWebServer.initialize, so the context never refreshes.
Root cause evidence
Contents of BOOT-INF/lib in the built bootJar - note Jackson 2 core and annotations are present, Jackson 3 databind is present, and Jackson 2 databind is missing:
BOOT-INF/lib/jackson-core-2.21.5.jar
BOOT-INF/lib/jackson-annotations-2.21.jar
BOOT-INF/lib/jackson-dataformat-cbor-2.21.4.jar
BOOT-INF/lib/jackson-dataformat-smile-2.21.4.jar
BOOT-INF/lib/jackson-dataformat-yaml-2.21.4.jar
BOOT-INF/lib/jackson-databind-3.1.5.jar
BOOT-INF/lib/jackson-core-3.1.5.jar
BOOT-INF/lib/spring-boot-jackson-4.1.0.jar
dependencyInsight shows the Jackson 2 core arriving transitively and being upgraded by the managed platform:
com.fasterxml.jackson.core:jackson-core:2.14.2 -> 2.21.5
\--- org.elasticsearch:elasticsearch-x-content:7.17.29
\--- org.elasticsearch:elasticsearch:7.17.29
\--- org.grails.plugins:grails-elasticsearch:5.1.0
com.fasterxml.jackson.core:jackson-core:2.21.4 -> 2.21.5
\--- org.springframework.boot:spring-boot-dependencies:4.1.0
Confirmation of the diagnosis
Adding the missing Jackson 2 databind to the same app:
runtimeOnly "com.fasterxml.jackson.core:jackson-databind:2.21.5"
makes the startup crash disappear entirely. The app then boots, the plugin wires up, and the only remaining failure is the plugin's own ConnectException reaching an Elasticsearch server - an unrelated, expected environmental error:
Caused by: org.elasticsearch.ElasticsearchException at RestHighLevelClient.java:2695
Caused by: java.util.concurrent.ExecutionException at BaseFuture.java:257
Caused by: java.net.ConnectException at Net.java:694
So the startup failure is purely the incomplete Jackson 2 classpath, not the plugin's behaviour.
Expected Behaviour
Either the managed platform keeps Jackson 2 internally consistent (if Jackson 2 jackson-core / jackson-annotations are managed and can reach the runtime classpath, Jackson 2 jackson-databind should be managed and present too), or Jackson 2 artifacts should not be able to reach the application runtime classpath at all, so Spring's Jackson 2 detection never triggers.
Right now a user gets a hard, non-obvious startup crash in an unrelated filter, with nothing pointing at the actual cause.
Impact
This is not specific to one plugin. Any Grails 7 plugin or third-party library that brings Jackson 2 core without databind - a very common shape, since many libraries depend on jackson-core or a Jackson 2 dataformat only - will take down a Grails 8 application at startup. The error message names neither Grails nor the offending dependency.
Suggested resolution
Options for discussion:
- Manage
com.fasterxml.jackson.core:jackson-databind(2.x) in the Grails platform alongside the Jackson 2jackson-core/jackson-annotations/ dataformat entries so the Jackson 2 classpath is never half-present. - Alternatively, keep Jackson 2 fully off the application runtime classpath and let Jackson 3 be the only Jackson present.
- At minimum, document this failure mode and the
runtimeOnly "com.fasterxml.jackson.core:jackson-databind:<2.x>"workaround in the Grails 8 upgrade guide's Jackson section, since the stack trace gives no hint.
Notes
Part of a compatibility sweep of released Grails 7 plugins against 8.0.0-M5. Related plugin-compatibility issues found in the same sweep: #16122 and #16123. Existing compatibility-shim precedents: #16011 and #16101.
- Lingua principale
- Groovy
- Stelle
- 2.9k
- Fork
- 978
- Merge medio
- 1g 2h
- PR unite (30g)
- 183
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un 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 apache/grails-core
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
apache/grails-core#16635 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
apache/grails-core#16289 · 5 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
apache/grails-core#15764 ·
I maintainer di solito rispondono entro 1 giorno
-
Update documentation for Java 25Forse già presa @ruthst00 l’ha presa 10 giorni fa. Apertarelates-to: documentation weekly-action-item
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
apache/grails-core#15725 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 40/100
apache/grails-core#16660 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di apache/grails-core
Issue simili
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
pop-os/cosmic-comp#2956 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
I maintainer di solito rispondono entro 1 giorno
-
GET rooms API returns 500 due to nonexistent Room.is_active attributeForse già presa @Mars-60 l’ha presa oggi. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 3 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
Chocobozzz/PeerTube#7832 ·
I maintainer di solito rispondono entro 3 giorni