jamesfredley commented on issue #16124:
URL: https://github.com/apache/grails-core/issues/16124#issuecomment-5243270261
### Follow-up: why `jackson-databind` 2 disappears, and how common this is
I resolved the runtime graphs of 13 released Grails plugins against
`org.apache.grails:grails-bom:8.0.0-M5` to see how widespread this is, and to
pin down why the Jackson 2 classpath ends up half-present. The result narrows
the problem usefully.
### It is specifically a *partial* Jackson 2 that breaks
Plugins that bring the **complete** Jackson 2 stack are fine, because
Spring's detection then finds the databind classes it expects:
| Plugin | Jackson 2 artifacts pulled | Verdict |
|---|---|---|
| `org.grails.plugins:grails-elasticsearch:5.1.0` | `jackson-core`,
`jackson-dataformat-cbor/smile/yaml` - **no databind** | **AT RISK** |
| `org.grails.plugins:grails-cache-redis:6.0.0-RC1` | `jackson-core`,
`jackson-annotations`, **`jackson-databind`**, `jackson-datatype-jdk8`,
`jackson-datatype-jsr310` | OK |
| `org.grails.plugins:sitemesh2:6.2.4` | same complete set including
**`jackson-databind`** | OK |
| `audit-logging:6.0.0`, `grails-web-console:7.1.0`,
`grails-logical-delete:3.0.0`, `grails-shiro:6.0.0`, `cache-ehcache:5.0.0-RC1`,
`grails-mail:5.0.3`, `grails-export:7.1.0`, `grails-quartz:4.0.1`,
`grails-redis:5.0.1`, `neo4j:8.1.0` | none | OK |
So the trigger is narrow: a dependency that pulls Jackson 2 **core and/or
dataformats** while nothing supplies Jackson 2 **databind**.
### Where the databind dependency goes
The same plugin resolved **without** the Grails BOM does include Jackson 2
databind:
```
=== ELASTICSEARCH WITHOUT GRAILS BOM ===
com.fasterxml.jackson.core:jackson-core:2.21.3
com.fasterxml.jackson.core:jackson-databind:2.21.3
com.fasterxml.jackson.core:jackson-annotations:2.21
com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.21.3
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.3
com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.21.3
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.3
```
With the 8.0.0-M5 BOM applied, `jackson-databind` 2 is gone entirely -
`dependencyInsight` reports `No dependencies matching given input were found in
configuration ':scan_elasticsearch'`.
This is **not** a BOM exclusion. `grails-base-bom-8.0.0-M5.pom` still
manages it:
```xml
<jackson2.version>2.21.5</jackson2.version>
<jackson3.version>3.1.5</jackson3.version>
...
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson2.version}</version>
</dependency>
```
The cause is that the only *path* to Jackson 2 databind was the plugin's
Grails 7 dependencies. The plugin requests `org.apache.grails:*:7.0.11`, and
the Grails 8 BOM upgrades those to `8.0.0-M5`, which moved to Jackson 3
(`tools.jackson`). Upgrading them removes the edge that used to supply Jackson
2 databind.
Meanwhile the **non-Grails** transitives are untouched.
`org.elasticsearch:elasticsearch-x-content:7.17.29` depends on `jackson-core`
and the three dataformats but not on databind:
```
+--- com.fasterxml.jackson.core:jackson-core:2.14.2 -> 2.21.5
+--- com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.14.2 ->
2.21.4
+--- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.14.2 ->
2.21.4
\--- com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.14.2 ->
2.21.4
```
Those survive the BOM upgrade, so the app is left with Jackson 2 core plus
dataformats and no Jackson 2 databind - exactly the state Spring Framework 7
mishandles.
### Why this generalises
Any Grails 7 plugin in this shape hits it:
1. it depends on Grails 7 artifacts (so it inherited Jackson 2 databind
transitively), **and**
2. it also depends on a non-Grails library that pulls Jackson 2 core or a
Jackson 2 dataformat directly.
Condition 1 is true of essentially every Grails 7 plugin. Condition 2 is
common for anything wrapping a client library - Elasticsearch, Kafka, AWS SDKs,
CBOR/Smile/YAML users. The plugin author does nothing wrong and nothing in
their build changes; the classpath simply becomes inconsistent when the Grails
BOM upgrades the Grails half to Jackson 3.
That also means the sample above understates it - it only counts plugins I
resolved, and any app dependency (not just a plugin) in shape 2 does the same
thing.
### Bearing on the fix
Since the BOM already manages
`com.fasterxml.jackson.core:jackson-databind:2.21.5`, the smallest fix may be
to ensure Jackson 2 databind is *present* whenever Jackson 2 core is on the
runtime classpath, rather than merely version-managed. Otherwise the failure
stays silent until Tomcat start, and the stack trace names neither Grails nor
the dependency responsible.
--
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]