This is an automated email from the ASF dual-hosted git repository.
FrankChen021 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 2f35573537a build(deps): Bump jackson to `2.21.3` (#19528)
2f35573537a is described below
commit 2f35573537a46f2afca1e239f232db56f57284e7
Author: Andreas Maechler <[email protected]>
AuthorDate: Fri May 29 07:50:04 2026 -0600
build(deps): Bump jackson to `2.21.3` (#19528)
* Bump jackson to 2.21.3
Jackson 2.21 (issue #1381) changed the default resolution of
@JacksonInject when combined with @JsonProperty on the same parameter:
the injected value now wins over the JSON value, where 2.20 treated
the inject as a fallback used only when JSON did not supply one.
DruidNode's serviceName, port, and tlsPort parameters carry both
annotations, with JSON expected to win when supplied — this is how
DruidNode JSON config files have always worked. Add the explicit
useInput = OptBoolean.TRUE to restore that contract.
A repo-wide audit confirmed DruidNode's three parameters are the only
sites in Druid where @JacksonInject and @JsonProperty annotate the
same parameter; everywhere else the annotations are on distinct
parameters and are unaffected.
Also adds the previously-missing license entry for org.jspecify:jspecify
1.0.0 in extensions-core/kubernetes-extensions, which the
check-licenses dependency report flagged.
* Preserve @JacksonInject metadata in GuiceAnnotationIntrospector
findInjectableValue was returning JacksonInject.Value.forId(id), which
strips useInput and optional from the original annotation. Production
deserialization happens to remain correct under jackson 2.21 because
AnnotationIntrospectorPair.findInjectableValue falls back to the
secondary (default Jackson) introspector and merges the recovered
useInput onto the primary's Value via withUseInput.
That fallback is undocumented as part of the introspector contract and
would silently regress if the pair semantics change, or if this
introspector were ever installed standalone for a special-purpose
mapper. Construct the Value via JacksonInject.Value.from(annotation)
.withId(id) so the introspector returns a complete Value on its own
and no longer relies on the pair to fix it up.
The annotation lookup is hoisted to the top of findInjectableValue so
the non-null contract between it and findGuiceInjectId is explicit —
findGuiceInjectId now documents the precondition and trusts the caller
to verify, eliminating the duplicate getAnnotation call.
Defensive cleanup motivated by FasterXML/jackson-databind#1381; no
observable behavior change.
---
licenses.yaml | 20 +++++++++++++++-----
pom.xml | 2 +-
.../druid/guice/GuiceAnnotationIntrospector.java | 18 ++++++++++++------
.../main/java/org/apache/druid/server/DruidNode.java | 7 ++++---
4 files changed, 32 insertions(+), 15 deletions(-)
diff --git a/licenses.yaml b/licenses.yaml
index 23f58a0d3b3..8032c582975 100644
--- a/licenses.yaml
+++ b/licenses.yaml
@@ -321,7 +321,7 @@ name: Jackson
license_category: binary
module: java-core
license_name: Apache License version 2.0
-version: 2.20.2
+version: 2.21.3
libraries:
- com.fasterxml.jackson.core: jackson-core
- com.fasterxml.jackson.core: jackson-annotations
@@ -364,7 +364,7 @@ name: Jackson
license_category: binary
module: java-core
license_name: Apache License version 2.0
-version: "2.20"
+version: "2.21"
libraries:
- com.fasterxml.jackson.core: jackson-annotations
@@ -374,7 +374,7 @@ name: Jackson
license_category: binary
module: extensions-contrib/druid-deltalake-extensions
license_name: Apache License version 2.0
-version: 2.20.2
+version: 2.21.3
libraries:
- com.fasterxml.jackson.core: jackson-databind
notice: |
@@ -1002,7 +1002,7 @@ name: Jackson
license_category: binary
module: extensions-core/kubernetes-overlord-extensions
license_name: Apache License version 2.0
-version: 2.20.2
+version: 2.21.3
libraries:
- com.fasterxml.jackson.dataformat: jackson-dataformat-properties
notice: |
@@ -1107,6 +1107,16 @@ libraries:
---
+name: org.jspecify jspecify
+license_category: binary
+module: extensions-core/kubernetes-extensions
+license_name: Apache License version 2.0
+version: 1.0.0
+libraries:
+ - org.jspecify: jspecify
+
+---
+
name: io.gsonfire gson-fire
license_category: binary
module: extensions-core/kubernetes-extensions
@@ -3069,7 +3079,7 @@ libraries:
---
name: Jackson Dataformat Yaml
-version: 2.20.2
+version: 2.21.3
license_category: binary
module: extensions/druid-avro-extensions
license_name: Apache License version 2.0
diff --git a/pom.xml b/pom.xml
index aabb17d07f0..fa07aa254c1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -105,7 +105,7 @@
<iceberg.core.version>1.10.0</iceberg.core.version>
<jetty.version>12.1.8</jetty.version>
<jersey.version>1.19.4</jersey.version>
- <jackson.version>2.20.2</jackson.version>
+ <jackson.version>2.21.3</jackson.version>
<codehaus.jackson.version>1.9.13</codehaus.jackson.version>
<log4j.version>2.25.4</log4j.version>
<mysql.version>8.2.0</mysql.version>
diff --git
a/processing/src/main/java/org/apache/druid/guice/GuiceAnnotationIntrospector.java
b/processing/src/main/java/org/apache/druid/guice/GuiceAnnotationIntrospector.java
index fd8ee5e9e02..890e3c233a0 100644
---
a/processing/src/main/java/org/apache/druid/guice/GuiceAnnotationIntrospector.java
+++
b/processing/src/main/java/org/apache/druid/guice/GuiceAnnotationIntrospector.java
@@ -44,19 +44,25 @@ public class GuiceAnnotationIntrospector extends
NopAnnotationIntrospector
@Override
public JacksonInject.Value findInjectableValue(AnnotatedMember m)
{
- Object id = findGuiceInjectId(m);
+ // Preserve useInput / optional from the annotation. The simpler
Value.forId(id) drops
+ // them and relies on AnnotationIntrospectorPair's fallback. See
FasterXML/jackson-databind#1381.
+ final JacksonInject annotation = m.getAnnotation(JacksonInject.class);
+ if (annotation == null) {
+ return null;
+ }
+ final Object id = findGuiceInjectId(m);
if (id == null) {
return null;
}
- return JacksonInject.Value.forId(id);
+ return JacksonInject.Value.from(annotation).withId(id);
}
+ /**
+ * Resolves the Guice {@link Key} for an annotated member. Callers must
verify that {@code m}
+ * carries a {@link JacksonInject} annotation before invoking; this method
does not re-check.
+ */
private Object findGuiceInjectId(AnnotatedMember m)
{
- if (m.getAnnotation(JacksonInject.class) == null) {
- return null;
- }
-
Type genericType = null;
Annotation guiceAnnotation = null;
diff --git a/server/src/main/java/org/apache/druid/server/DruidNode.java
b/server/src/main/java/org/apache/druid/server/DruidNode.java
index 820d8d32a08..19252fde755 100644
--- a/server/src/main/java/org/apache/druid/server/DruidNode.java
+++ b/server/src/main/java/org/apache/druid/server/DruidNode.java
@@ -22,6 +22,7 @@ package org.apache.druid.server;
import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.OptBoolean;
import com.google.common.base.Preconditions;
import com.google.common.net.HostAndPort;
import com.google.inject.name.Named;
@@ -130,12 +131,12 @@ public class DruidNode
*/
@JsonCreator
public DruidNode(
- @JacksonInject @Named("serviceName") @JsonProperty("service") String
serviceName,
+ @JacksonInject(useInput = OptBoolean.TRUE) @Named("serviceName")
@JsonProperty("service") String serviceName,
@JsonProperty("host") String host,
@JsonProperty("bindOnHost") boolean bindOnHost,
@JsonProperty("plaintextPort") Integer plaintextPort,
- @JacksonInject @Named("servicePort") @JsonProperty("port") Integer port,
- @JacksonInject @Named("tlsServicePort") @JsonProperty("tlsPort") Integer
tlsPort,
+ @JacksonInject(useInput = OptBoolean.TRUE) @Named("servicePort")
@JsonProperty("port") Integer port,
+ @JacksonInject(useInput = OptBoolean.TRUE) @Named("tlsServicePort")
@JsonProperty("tlsPort") Integer tlsPort,
@JsonProperty("enablePlaintextPort") Boolean enablePlaintextPort,
@JsonProperty("enableTlsPort") boolean enableTlsPort,
@JsonProperty("labels") @Nullable Map<String, String> labels
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]