jamesfredley commented on issue #16124:
URL: https://github.com/apache/grails-core/issues/16124#issuecomment-5243619656
### Correction and a minimal reproduction with no plugin involved
I stated above that this affects "any dependency bringing Jackson 2 core
without databind". That was too broad - I had only demonstrated it through the
Elasticsearch plugin. I bisected it in a stock 8.0.0-M5 app and the real
trigger is narrower and more specific.
### Bisection results
Stock `grails create-app --profile=web` on 8.0.0-M5, adding only the listed
dependencies, asserting nothing more than that the application context starts:
| Added to a stock app | Result |
|---|---|
| `com.fasterxml.jackson.core:jackson-core:2.21.5` | **starts fine** |
| `jackson-core:2.21.5` + `jackson-annotations:2.21` | **starts fine** |
| a single Jackson 2 **dataformat** with `jackson-databind` excluded |
**fails to start** |
So Jackson 2 `jackson-core`, with or without `jackson-annotations`, is
harmless. The trigger is a Jackson 2 **dataformat** artifact present while
Jackson 2 `jackson-databind` is absent.
### Minimal reproduction
This is the whole thing - no plugin, three lines in a stock app:
```groovy
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.21.4")
{
exclude group: 'com.fasterxml.jackson.core', module: 'jackson-databind'
}
```
```
BootSpec > the application context starts FAILED
Caused by: org.springframework.boot.web.server.WebServerException at
TomcatWebServer.java:150
Caused by: java.lang.NoClassDefFoundError at
DefaultHttpMessageConverters.java:334
Caused by: java.lang.ClassNotFoundException at
BuiltinClassLoader.java:641
```
`jackson-dataformat-cbor` and `jackson-dataformat-yaml` behave the same way;
I originally hit all three together via Elasticsearch.
This makes sense mechanically: Spring's
`DefaultHttpMessageConverters.detectMessageConverters()` sees the
Smile/CBOR/YAML dataformat classes, concludes Jackson 2 support is available,
and then builds a Jackson 2 converter that hard-references a `jackson-databind`
class.
### How the databind gap arises in practice
The explicit `exclude` above is just the shortest way to force the state. In
a real build it happens two ways:
1. **A library excludes databind itself.**
`org.elasticsearch:elasticsearch-x-content` depends on `jackson-core` and the
three dataformats without pulling databind, which is how the original report
arose.
2. **The BOM upgrade removes the only databind path**, as described in my
previous comment: the plugin's Grails 7 dependencies supplied Jackson 2
databind, and upgrading them to 8.0.0-M5 (Jackson 3) deletes that edge while
the dataformats survive.
### Revised impact
Narrower than I first said, but still not rare, and worth keeping:
- It needs a Jackson 2 **dataformat**, not merely Jackson 2 core. CBOR,
Smile, YAML, and presumably XML are common in client libraries (Elasticsearch,
Kafka, various AWS and protobuf-adjacent stacks).
- It is **not plugin-specific** - the reproduction above has no Grails
plugin at all, which was the part of my original claim that does hold.
- The failure is still total (Tomcat never starts) and still points at
`OrderedFormContentFilter` rather than at the responsible dependency.
Apologies for the imprecision in the original write-up; the bisected trigger
above should be the one to design against.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]