Skip to content

Commit 5039752

Browse files
committed
Update test and docs to mention that only Spark 3 is affected
1 parent cf2432e commit 5039752

2 files changed

Lines changed: 25 additions & 20 deletions

File tree

docs/modules/spark-k8s/pages/usage-guide/spark-connect.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,9 @@ The following features are not supported by the Stackable Spark operator yet
198198

199199
== Known Issues
200200

201-
* Distributed operations on Apache Iceberg tables fail on the executors.
201+
* Distributed operations on Apache Iceberg tables fail on the executors *with Spark 3.5.x*.
202202
PySpark calls that trigger a distributed job over an Iceberg table -- for example `DataFrame.collect()` or `DataFrame.count()` -- fail with `java.lang.ClassCastException: cannot assign instance of java.lang.invoke.SerializedLambda to field org.apache.spark.rdd.MapPartitionsRDD.f of type scala.Function3`.
203203
Driver-only operations still work: DDL (`CREATE`/`DROP`), `INSERT` of small data, `DataFrame.show()` of a small result, `SHOW TABLES` and `DESCRIBE`.
204204
The cause is upstream in Spark Connect: executor tasks run under a per-session class loader (which fetches session classes from the driver's artifact server) that cannot deserialize the Iceberg scan closures.
205205
It is independent of how the Iceberg runtime is provisioned -- it reproduces with `--packages`, with the jar placed on the system class path (`/stackable/spark/jars`), with `spark.addArtifact()`, and with combinations of these.
206-
See https://issues.apache.org/jira/browse/SPARK-46032[SPARK-46032] (open) and https://issues.apache.org/jira/browse/SPARK-51537[SPARK-51537] for details.
206+
*This is fixed in Spark 4* (https://issues.apache.org/jira/browse/SPARK-51537[SPARK-51537] / https://github.com/apache/spark/pull/50475[apache/spark#50475]), where distributed reads and writes of Iceberg tables work; it is not backported to the 3.5.x line (see the still-open https://issues.apache.org/jira/browse/SPARK-46032[SPARK-46032]).

tests/templates/kuttl/spark-connect-kerberos/20-run-connect-client.yaml.j2

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -57,25 +57,30 @@ data:
5757
spark.sql("DROP TABLE IF EXISTS iceberg.lakehouse.greetings")
5858
spark.sql("CREATE TABLE iceberg.lakehouse.greetings (id INT, data STRING) USING iceberg")
5959
spark.sql("INSERT INTO iceberg.lakehouse.greetings VALUES (1, 'one'), (2, 'two'), (3, 'three')")
60-
spark.sql("SELECT * FROM iceberg.lakehouse.greetings ORDER BY id").show()
6160

62-
# Verify the Iceberg table is registered in the kerberized metastore via a
63-
# metastore query (driver-side). We deliberately avoid result.collect() /
64-
# count() over the Iceberg table: a *distributed* scan ships the Iceberg
65-
# RDD closure to the executors, where it currently fails to deserialize on
66-
# Spark Connect ("cannot assign SerializedLambda ... Function3"). This is an
67-
# upstream Spark Connect classloader limitation (see SPARK-46032 /
68-
# SPARK-51537) independent of how the Iceberg jar is provisioned - it
69-
# reproduces with --packages, with the jar on the system classpath, with
70-
# spark.addArtifact(), and with --packages + addArtifact together - and is
71-
# separate from the metastore/Kerberos integration this test validates.
72-
ice_tables = [row.tableName for row in spark.sql("SHOW TABLES IN iceberg.lakehouse").collect()]
73-
print("Tables in 'iceberg.lakehouse':", ice_tables)
74-
assert "greetings" in ice_tables, f"Iceberg table not registered in the HMS: {ice_tables}"
75-
76-
ice_columns = [row.col_name for row in spark.sql("DESCRIBE TABLE iceberg.lakehouse.greetings").collect()]
77-
print("Columns of iceberg.lakehouse.greetings:", ice_columns)
78-
assert "id" in ice_columns and "data" in ice_columns, f"unexpected columns: {ice_columns}"
61+
# Reading the Iceberg table back differs by Spark version:
62+
#
63+
# Spark 4 includes the Spark Connect executor class loader fix
64+
# (SPARK-51537 / apache/spark#50475), so a *distributed* read works:
65+
# collect() ships the Iceberg scan closure to the executors and succeeds.
66+
#
67+
# On Spark 3.5.x that distributed scan still fails on the executors with
68+
# "cannot assign SerializedLambda ... Function3" (SPARK-46032, not fixed in
69+
# 3.5.x), so we verify the table via metastore queries (driver-side) instead.
70+
print(f"Connected to Spark {spark.version}")
71+
if spark.version.startswith("4"):
72+
result = spark.sql("SELECT * FROM iceberg.lakehouse.greetings ORDER BY id")
73+
result.show()
74+
rows = result.collect()
75+
assert len(rows) == 3, f"expected 3 rows in the Iceberg table, got {len(rows)}"
76+
else:
77+
spark.sql("SELECT * FROM iceberg.lakehouse.greetings ORDER BY id").show()
78+
ice_tables = [row.tableName for row in spark.sql("SHOW TABLES IN iceberg.lakehouse").collect()]
79+
print("Tables in 'iceberg.lakehouse':", ice_tables)
80+
assert "greetings" in ice_tables, f"Iceberg table not registered in the HMS: {ice_tables}"
81+
ice_columns = [row.col_name for row in spark.sql("DESCRIBE TABLE iceberg.lakehouse.greetings").collect()]
82+
print("Columns of iceberg.lakehouse.greetings:", ice_columns)
83+
assert "id" in ice_columns and "data" in ice_columns, f"unexpected columns: {ice_columns}"
7984

8085
print("[SUCCESS] Read/write against the kerberized Hive metastore and Iceberg catalog succeeded")
8186

0 commit comments

Comments
 (0)