This is an automated email from the ASF dual-hosted git repository.
dongjoon pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/branch-4.1 by this push:
new beedbda4a27f [SPARK-54146][CORE][SQL] Clean up the usage of deprecated
Jackson API
beedbda4a27f is described below
commit beedbda4a27f72bad07c64a0f69c4db3fa2cf5c9
Author: yangjie01 <[email protected]>
AuthorDate: Mon Nov 3 22:08:23 2025 +0800
[SPARK-54146][CORE][SQL] Clean up the usage of deprecated Jackson API
### What changes were proposed in this pull request?
This PR cleans up the usage of deprecated Jackson APIs as follows:
```
Applicable -Wconf / nowarn filters for this warning: msg=<part of the
message>, cat=deprecation,
site=org.apache.spark.ErrorClassesJsonReader.readAsMap.map,
origin=com.fasterxml.jackson.databind.ObjectMapper.readValue
Applicable -Wconf / nowarn filters for this warning: msg=<part of the
message>, cat=deprecation,
site=org.apache.spark.status.KVUtils.KVStoreScalaSerializer,
origin=com.fasterxml.jackson.databind.ObjectMapper.setSerializationInclusion
Applicable -Wconf / nowarn filters for this warning: msg=<part of the
message>, cat=deprecation,
site=org.apache.spark.status.api.v1.JacksonMessageWriter,
origin=com.fasterxml.jackson.databind.ObjectMapper.setSerializationInclusion
Applicable -Wconf / nowarn filters for this warning: msg=<part of the
message>, cat=deprecation, site=org.apache.spark.SparkThrowableSuite,
origin=com.fasterxml.jackson.databind.ObjectMapper.readValue
Applicable -Wconf / nowarn filters for this warning: msg=<part of the
message>, cat=deprecation, site=org.apache.spark.SparkThrowableSuite,
origin=com.fasterxml.jackson.databind.ObjectMapper.setSerializationInclusion
Applicable -Wconf / nowarn filters for this warning: msg=<part of the
message>, cat=deprecation, site=org.apache.spark.SparkThrowableSuite,
origin=com.fasterxml.jackson.databind.ObjectMapper.readValue
Applicable -Wconf / nowarn filters for this warning: msg=<part of the
message>, cat=deprecation, site=org.apache.spark.SparkThrowableSuite,
origin=com.fasterxml.jackson.databind.ObjectMapper.readValue
Applicable -Wconf / nowarn filters for this warning: msg=<part of the
message>, cat=deprecation,
site=org.apache.spark.sql.catalyst.util.RebaseDateTime.loadRebaseRecords.jsonRebaseRecords,
origin=com.fasterxml.jackson.module.scala.ClassTagExtensions.readValue,
version=2.20.0
Applicable -Wconf / nowarn filters for this warning: msg=<part of the
message>, cat=deprecation,
site=org.apache.spark.sql.catalyst.catalog.UserDefinedFunction.getObjectMapper,
origin=com.fasterxml.jackson.databind.ObjectMapper.setSerializationInclusion
Applicable -Wconf / nowarn filters for this warning: msg=<part of the
message>, cat=deprecation,
site=org.apache.spark.sql.catalyst.catalog.ClusterBySpec.mapper,
origin=com.fasterxml.jackson.databind.ObjectMapper.setSerializationInclusion
Applicable -Wconf / nowarn filters for this warning: msg=<part of the
message>, cat=deprecation,
site=org.apache.spark.sql.execution.streaming.state.RocksDBCheckpointMetadata.mapper,
origin=com.fasterxml.jackson.databind.ObjectMapper.setSerializationInclusion
```
Relevant modifications reference:
1. Replace `T readValue(URL src, TypeReference<T> valueTypeRef)` with `T
readValue(InputStream src, TypeReference<T> valueTypeRef)`
https://github.com/FasterXML/jackson-databind/blob/4260f88180e5e45f3be1a290114e55c042bb2213/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java#L3848-L3877
```
/**
* Method to deserialize JSON content from given resource into given
Java type.
*<p>
* NOTE: handling of {link java.net.URL} is delegated to
* {link JsonFactory#createParser(java.net.URL)} and usually simply
* calls {link java.net.URL#openStream()}, meaning no special handling
* is done. If different HTTP connection options are needed you will
need
* to create {link java.io.InputStream} separately.
*
* throws IOException if a low-level I/O problem (unexpected
end-of-input,
* network error) occurs (passed through as-is without additional
wrapping -- note
* that this is one case where {link
DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* throws StreamReadException if underlying input contains invalid
content
* of type {link JsonParser} supports (JSON for default case)
* throws DatabindException if the input JSON structure does not match
structure
* expected for result type (or has other mismatch issues)
*
* deprecated since 2.20 deprecated as it calls {link
JsonFactory#createParser(URL)}.
* Instead, use equivalent methods that take InputStream
inputs instead.
*/
Deprecated // since 2.20
SuppressWarnings("unchecked")
public <T> T readValue(URL src, Class<T> valueType)
throws IOException, StreamReadException, DatabindException
{
_assertNotNull("src", src);
return (T) _readMapAndClose(_jsonFactory.createParser(src),
_typeFactory.constructType(valueType));
}
```
2. Replace `ObjectMapper setSerializationInclusion(JsonInclude.Include
incl)` with `ObjectMapper setDefaultPropertyInclusion(JsonInclude.Value incl)`
https://github.com/FasterXML/jackson-databind/blob/4260f88180e5e45f3be1a290114e55c042bb2213/src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java#L1853-L1872
```
/**
* Convenience method, equivalent to calling:
*<pre>
* setPropertyInclusion(JsonInclude.Value.construct(incl, incl));
*</pre>
*<p>
* NOTE: behavior differs slightly from 2.8, where second argument was
* implied to be <code>JsonInclude.Include.ALWAYS</code>.
*<p>
* NOTE: in Jackson 3.x all configuration goes through {code
ObjectMapper} builders,
* see {link com.fasterxml.jackson.databind.cfg.MapperBuilder},
* and this method will be removed from 3.0.
*
* deprecated Since 2.9 use {link
#setDefaultPropertyInclusion(JsonInclude.Include)}
*/
Deprecated
public ObjectMapper setSerializationInclusion(JsonInclude.Include incl)
{
setPropertyInclusion(JsonInclude.Value.construct(incl, incl));
return this;
}
```
### Why are the changes needed?
To clean up the usage of deprecated APIs and align with Jackson's
recommended practices.
### Does this PR introduce _any_ user-facing change?
No
### How was this patch tested?
Pass Github Actions
### Was this patch authored or co-authored using generative AI tooling?
No
Closes #52845 from LuciferYang/jackson-deprecation.
Lead-authored-by: yangjie01 <[email protected]>
Co-authored-by: YangJie <[email protected]>
Signed-off-by: yangjie01 <[email protected]>
(cherry picked from commit 46e7bfb58141bea9c51066d789bb228373977e9c)
Signed-off-by: Dongjoon Hyun <[email protected]>
---
.../src/main/scala/org/apache/spark/ErrorClassesJSONReader.scala | 2 +-
core/src/main/scala/org/apache/spark/status/KVUtils.scala | 2 +-
.../org/apache/spark/status/api/v1/JacksonMessageWriter.scala | 2 +-
core/src/test/scala/org/apache/spark/SparkThrowableSuite.scala | 9 +++++----
.../org/apache/spark/sql/catalyst/util/RebaseDateTime.scala | 2 +-
.../apache/spark/sql/catalyst/catalog/UserDefinedFunction.scala | 2 +-
.../scala/org/apache/spark/sql/catalyst/catalog/interface.scala | 2 +-
.../spark/sql/execution/streaming/state/RocksDBFileManager.scala | 2 +-
8 files changed, 12 insertions(+), 11 deletions(-)
diff --git
a/common/utils/src/main/scala/org/apache/spark/ErrorClassesJSONReader.scala
b/common/utils/src/main/scala/org/apache/spark/ErrorClassesJSONReader.scala
index af76056dfe92..0d958e3f7160 100644
--- a/common/utils/src/main/scala/org/apache/spark/ErrorClassesJSONReader.scala
+++ b/common/utils/src/main/scala/org/apache/spark/ErrorClassesJSONReader.scala
@@ -152,7 +152,7 @@ private object ErrorClassesJsonReader {
.addModule(DefaultScalaModule)
.build()
private def readAsMap(url: URL): Map[String, ErrorInfo] = {
- val map = mapper.readValue(url, new TypeReference[Map[String,
ErrorInfo]]() {})
+ val map = mapper.readValue(url.openStream(), new TypeReference[Map[String,
ErrorInfo]]() {})
val errorClassWithDots = map.collectFirst {
case (errorClass, _) if errorClass.contains('.') => errorClass
case (_, ErrorInfo(_, Some(map), _, _)) if
map.keys.exists(_.contains('.')) =>
diff --git a/core/src/main/scala/org/apache/spark/status/KVUtils.scala
b/core/src/main/scala/org/apache/spark/status/KVUtils.scala
index 76fb654f8da2..1a9d36f6c647 100644
--- a/core/src/main/scala/org/apache/spark/status/KVUtils.scala
+++ b/core/src/main/scala/org/apache/spark/status/KVUtils.scala
@@ -74,7 +74,7 @@ private[spark] object KVUtils extends Logging {
private[spark] class KVStoreScalaSerializer extends KVStoreSerializer {
mapper.registerModule(DefaultScalaModule)
- mapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
+ mapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_ABSENT)
}
diff --git
a/core/src/main/scala/org/apache/spark/status/api/v1/JacksonMessageWriter.scala
b/core/src/main/scala/org/apache/spark/status/api/v1/JacksonMessageWriter.scala
index 259d0aacc575..1103f5529782 100644
---
a/core/src/main/scala/org/apache/spark/status/api/v1/JacksonMessageWriter.scala
+++
b/core/src/main/scala/org/apache/spark/status/api/v1/JacksonMessageWriter.scala
@@ -48,7 +48,7 @@ private[v1] class JacksonMessageWriter extends
MessageBodyWriter[Object]{
}
mapper.registerModule(com.fasterxml.jackson.module.scala.DefaultScalaModule)
mapper.enable(SerializationFeature.INDENT_OUTPUT)
- mapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
+ mapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_ABSENT)
mapper.setDateFormat(JacksonMessageWriter.makeISODateFormat)
override def isWriteable(
diff --git a/core/src/test/scala/org/apache/spark/SparkThrowableSuite.scala
b/core/src/test/scala/org/apache/spark/SparkThrowableSuite.scala
index d182bd165f1f..24a1fa740175 100644
--- a/core/src/test/scala/org/apache/spark/SparkThrowableSuite.scala
+++ b/core/src/test/scala/org/apache/spark/SparkThrowableSuite.scala
@@ -75,7 +75,8 @@ class SparkThrowableSuite extends SparkFunSuite {
.addModule(DefaultScalaModule)
.enable(STRICT_DUPLICATE_DETECTION)
.build()
- mapper.readValue(errorJsonFilePath.toUri.toURL, new
TypeReference[Map[String, ErrorInfo]]() {})
+ mapper.readValue(
+ errorJsonFilePath.toUri.toURL.openStream(), new
TypeReference[Map[String, ErrorInfo]]() {})
}
test("Error conditions are correctly formatted") {
@@ -88,7 +89,7 @@ class SparkThrowableSuite extends SparkFunSuite {
val prettyPrinter = new DefaultPrettyPrinter()
.withArrayIndenter(DefaultIndenter.SYSTEM_LINEFEED_INSTANCE)
val rewrittenString =
mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true)
- .setSerializationInclusion(Include.NON_ABSENT)
+ .setDefaultPropertyInclusion(Include.NON_ABSENT)
.writer(prettyPrinter)
.writeValueAsString(errorReader.errorInfoMap)
@@ -124,9 +125,9 @@ class SparkThrowableSuite extends SparkFunSuite {
.enable(STRICT_DUPLICATE_DETECTION)
.build()
val errorClasses = mapper.readValue(
- errorClassesJson, new TypeReference[Map[String, String]]() {})
+ errorClassesJson.openStream(), new TypeReference[Map[String, String]]()
{})
val errorStates = mapper.readValue(
- errorStatesJson, new TypeReference[Map[String, ErrorStateInfo]]() {})
+ errorStatesJson.openStream(), new TypeReference[Map[String,
ErrorStateInfo]]() {})
val errorConditionStates =
errorReader.errorInfoMap.values.toSeq.flatMap(_.sqlState).toSet
assert(Set("22012", "22003", "42601").subsetOf(errorStates.keySet))
assert(errorClasses.keySet.filter(!_.matches("[A-Z0-9]{2}")).isEmpty)
diff --git
a/sql/api/src/main/scala/org/apache/spark/sql/catalyst/util/RebaseDateTime.scala
b/sql/api/src/main/scala/org/apache/spark/sql/catalyst/util/RebaseDateTime.scala
index 8dff1ceccfcf..ca8e73a517d5 100644
---
a/sql/api/src/main/scala/org/apache/spark/sql/catalyst/util/RebaseDateTime.scala
+++
b/sql/api/src/main/scala/org/apache/spark/sql/catalyst/util/RebaseDateTime.scala
@@ -288,7 +288,7 @@ object RebaseDateTime {
// `JsonRebaseRecord`. Mutable HashMap is used here instead of AnyRefMap due
to SPARK-49491.
private[sql] def loadRebaseRecords(fileName: String): HashMap[String,
RebaseInfo] = {
val file = SparkClassUtils.getSparkClassLoader.getResource(fileName)
- val jsonRebaseRecords = mapper.readValue[Seq[JsonRebaseRecord]](file)
+ val jsonRebaseRecords =
mapper.readValue[Seq[JsonRebaseRecord]](file.openStream())
val hashMap = new HashMap[String, RebaseInfo]
hashMap.sizeHint(jsonRebaseRecords.size)
jsonRebaseRecords.foreach { jsonRecord =>
diff --git
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/UserDefinedFunction.scala
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/UserDefinedFunction.scala
index 8ed241468352..3365b11b0742 100644
---
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/UserDefinedFunction.scala
+++
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/UserDefinedFunction.scala
@@ -132,7 +132,7 @@ object UserDefinedFunction {
*/
private def getObjectMapper: ObjectMapper = {
val mapper = new ObjectMapper with ClassTagExtensions
- mapper.setSerializationInclusion(Include.NON_ABSENT)
+ mapper.setDefaultPropertyInclusion(Include.NON_ABSENT)
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
mapper.registerModule(DefaultScalaModule)
mapper
diff --git
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/interface.scala
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/interface.scala
index 64d816587f4d..07d26813be94 100644
---
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/interface.scala
+++
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/catalog/interface.scala
@@ -278,7 +278,7 @@ case class ClusterBySpec(columnNames: Seq[NamedReference]) {
object ClusterBySpec {
private val mapper = {
val ret = new ObjectMapper() with ClassTagExtensions
- ret.setSerializationInclusion(Include.NON_ABSENT)
+ ret.setDefaultPropertyInclusion(Include.NON_ABSENT)
ret.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
ret.registerModule(DefaultScalaModule)
ret
diff --git
a/sql/core/src/main/scala/org/apache/spark/sql/execution/streaming/state/RocksDBFileManager.scala
b/sql/core/src/main/scala/org/apache/spark/sql/execution/streaming/state/RocksDBFileManager.scala
index 7bef692e264a..2e86ff70d58f 100644
---
a/sql/core/src/main/scala/org/apache/spark/sql/execution/streaming/state/RocksDBFileManager.scala
+++
b/sql/core/src/main/scala/org/apache/spark/sql/execution/streaming/state/RocksDBFileManager.scala
@@ -1123,7 +1123,7 @@ object RocksDBCheckpointMetadata {
/** Used to convert between classes and JSON. */
lazy val mapper = {
val _mapper = new ObjectMapper with ClassTagExtensions
- _mapper.setSerializationInclusion(Include.NON_ABSENT)
+ _mapper.setDefaultPropertyInclusion(Include.NON_ABSENT)
_mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
_mapper.registerModule(DefaultScalaModule)
_mapper
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]