我刚刚发现一个有趣的现象,当从Scala代码生成的字节码被Java代码使用时,Scala作用域的行为非常奇怪。请考虑以下使用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
的。
你有什么想法?
Broadcast.destory
方法,相当于自己给自己惹麻烦。 - Yuval Itzchakov