[SPARK-3027] TaskContext: tighten visibility and provide Java friendly callback API

Note this also passes the TaskContext itself to the TaskCompletionListener. In the future we can mark TaskContext with the exception object if exception occurs during task execution.

I guess another option would be an implicit conversion from TaskContext => Unit to TaskCompletionListener, but that would require the user to import the implicits (maybe they could be included in the SparkContext implicits, though).