Я только узнал о довольно странном поведении Scala, когда байт-код, сгенерированный из кода Scala, используется из кода Java. Рассмотрим следующий фрагмент, используя Spark (Spark 1.4, Hadoop 2.6):
import java.util.Arrays;
import java.util.List;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.broadcast.Broadcast;
public class Test {
public static void main(String[] args) {
JavaSparkContext sc =
new JavaSparkContext(new SparkConf()
.setMaster("local[*]")
.setAppName("test"));
Broadcast<List<Integer>> broadcast = sc.broadcast(Arrays.asList(1, 2, 3));
broadcast.destroy(true);
// fails with java.io.IOException: org.apache.spark.SparkException:
// Attempted to use Broadcast(0) after it was destroyed
sc.parallelize(Arrays.asList("task1", "task2"), 2)
.foreach(x -> System.out.println(broadcast.getValue()));
}
}
Этот код терпит неудачу, ожидаемый, поскольку я добровольно уничтожаю Broadcast
перед его использованием, но дело в том, что в моей ментальной модели он даже не компилируется, не говоря уже о работе.
Действительно, Broadcast.destroy(Boolean)
объявляется как private[spark]
, поэтому он не должен быть видимым из моего кода. Я попытаюсь взглянуть на байт-код Broadcast
, но это не моя специальность, поэтому я предпочитаю публиковать этот вопрос. Кроме того, извините, мне было слишком ленив, чтобы создать пример, который не зависит от Spark, но по крайней мере вы получите эту идею. Обратите внимание, что я могу использовать различные приватно-частные методы Spark, это не только Broadcast
.
Любая идея о том, что происходит?