java+spark: org.apache.spark.SparkException: Job aborted: Task not serializable: java.io.NotSerializableException

The nested functions hold a reference to the containing object (JavaSparkPi). So this object will get serialized. For this to work, it needs to be serializable. Simple to do:

public class JavaSparkPi implements Serializable {
  ...

The main problem is that when you create an Anonymous Class in java it is passed a reference of the enclosing class. This can be fixed in many ways

Declare the enclosing class Serializable

This works in your case but will fall flat in case your enclosing class has some field that is not serializable. I would also say that serializing the parent class is a total waste.

Create the Closure in a static function

Creating the closure by invoking some static function doesn't pass the reference to the closure and hence no need to make serializable this way.