Skip to content
Snippets Groups Projects
Commit 73da9c26 authored by Takuya UESHIN's avatar Takuya UESHIN Committed by Michael Armbrust
Browse files

[SPARK-3771][SQL] AppendingParquetOutputFormat should use reflection to...

[SPARK-3771][SQL] AppendingParquetOutputFormat should use reflection to prevent from breaking binary-compatibility.

Original problem is [SPARK-3764](https://issues.apache.org/jira/browse/SPARK-3764).

`AppendingParquetOutputFormat` uses a binary-incompatible method `context.getTaskAttemptID`.
This causes binary-incompatible of Spark itself, i.e. if Spark itself is built against hadoop-1, the artifact is for only hadoop-1, and vice versa.

Author: Takuya UESHIN <ueshin@happy-camper.st>

Closes #2638 from ueshin/issues/SPARK-3771 and squashes the following commits:

efd3784 [Takuya UESHIN] Add a comment to explain the reason to use reflection.
ec213c1 [Takuya UESHIN] Use reflection to prevent breaking binary-compatibility.
parent d3cdf912
No related branches found
No related tags found
No related merge requests found
......@@ -331,13 +331,21 @@ private[parquet] class AppendingParquetOutputFormat(offset: Int)
// override to choose output filename so not overwrite existing ones
override def getDefaultWorkFile(context: TaskAttemptContext, extension: String): Path = {
val taskId: TaskID = context.getTaskAttemptID.getTaskID
val taskId: TaskID = getTaskAttemptID(context).getTaskID
val partition: Int = taskId.getId
val filename = s"part-r-${partition + offset}.parquet"
val committer: FileOutputCommitter =
getOutputCommitter(context).asInstanceOf[FileOutputCommitter]
new Path(committer.getWorkPath, filename)
}
// The TaskAttemptContext is a class in hadoop-1 but is an interface in hadoop-2.
// The signatures of the method TaskAttemptContext.getTaskAttemptID for the both versions
// are the same, so the method calls are source-compatible but NOT binary-compatible because
// the opcode of method call for class is INVOKEVIRTUAL and for interface is INVOKEINTERFACE.
private def getTaskAttemptID(context: TaskAttemptContext): TaskAttemptID = {
context.getClass.getMethod("getTaskAttemptID").invoke(context).asInstanceOf[TaskAttemptID]
}
}
/**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment