带有 Apache Spark 的 MVCE / Java 静态构造函数的反射错误?
MVCE with Apache Spark / Java Reflection Error on static constructor?
仅当使用 Apache Spark 运行 通过 spark-submit.sh 时出现此错误,此 运行 在 IntelliJ 中正常 运行 配置正常所以我很漂亮确信这是关于 Spark 如何访问我们想要私有的构造函数的:
Class org.apache.spark.deploy.SparkSubmit$ can not access a member of
class jpsgcs.thold.AnyOldClass with modifiers "public static"
这是 MVCE:
import java.io.IOException;
import java.io.Serializable;
class AnyOldClass implements Serializable {
public String anyOldString = null;
private AnyOldClass() throws IOException {
anyOldString = new String("hello dere");
}
public static void main(String[] args) throws Exception {
AnyOldClass anyOldInstance = new AnyOldClass();
anyOldInstance.go();
}
private void go() {
System.out.println("Visualize ");
}
}
以下错误的完整版本,此 MVCE 开始时是一个功能齐全的基于 Spark 的程序,在我们将构造函数设为私有之前运行良好。缺少 SparkContext 和 SparkConf 不是问题。
我们有这个 class 通过几个级别继承。为了制作那个 class 的 RDD,我们必须在继承链上向上移动大约五个级别,使所有这些级别都可序列化。序列化这么深的堆栈会变得很难看,对吧? (那是在我们尝试 Kryo 之前)
我们认为这是一种更好的方法 运行 每个核心一个工作器,从而每个核心一个 JVM。在每个 JVM 中,我们希望获得此 class 的一个实例。然后我们将使用我们在 JavaRDD 中并行化的另一个 class 来修改此 class 的内容,每个 core/JVM 一个分区,每个分区的每个元素都基于 RDD class 就地修改此 class。
请求的完整堆栈跟踪:
Exception in thread "main" java.lang.IllegalAccessException: Class org.apache.spark.deploy.SparkSubmit$ can not access a member of class jpsgcs.thold.AnyOldClass with modifiers "public static"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
at java.lang.reflect.Method.invoke(Method.java:490)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:672)
at org.apache.spark.deploy.SparkSubmit$.doRunMain(SparkSubmit.scala:180)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:205)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:120)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
您需要 class public
。默认情况下 classes 是包范围,这意味着它必须驻留在与 org.apache.spark.deploy.SparkSubmit
相同的包中才能调用其方法。
改变
class AnyOldClass implements Serializable {
到
public class AnyOldClass implements Serializable {
仅当使用 Apache Spark 运行 通过 spark-submit.sh 时出现此错误,此 运行 在 IntelliJ 中正常 运行 配置正常所以我很漂亮确信这是关于 Spark 如何访问我们想要私有的构造函数的:
Class org.apache.spark.deploy.SparkSubmit$ can not access a member of class jpsgcs.thold.AnyOldClass with modifiers "public static"
这是 MVCE:
import java.io.IOException;
import java.io.Serializable;
class AnyOldClass implements Serializable {
public String anyOldString = null;
private AnyOldClass() throws IOException {
anyOldString = new String("hello dere");
}
public static void main(String[] args) throws Exception {
AnyOldClass anyOldInstance = new AnyOldClass();
anyOldInstance.go();
}
private void go() {
System.out.println("Visualize ");
}
}
以下错误的完整版本,此 MVCE 开始时是一个功能齐全的基于 Spark 的程序,在我们将构造函数设为私有之前运行良好。缺少 SparkContext 和 SparkConf 不是问题。
我们有这个 class 通过几个级别继承。为了制作那个 class 的 RDD,我们必须在继承链上向上移动大约五个级别,使所有这些级别都可序列化。序列化这么深的堆栈会变得很难看,对吧? (那是在我们尝试 Kryo 之前)
我们认为这是一种更好的方法 运行 每个核心一个工作器,从而每个核心一个 JVM。在每个 JVM 中,我们希望获得此 class 的一个实例。然后我们将使用我们在 JavaRDD 中并行化的另一个 class 来修改此 class 的内容,每个 core/JVM 一个分区,每个分区的每个元素都基于 RDD class 就地修改此 class。
请求的完整堆栈跟踪:
Exception in thread "main" java.lang.IllegalAccessException: Class org.apache.spark.deploy.SparkSubmit$ can not access a member of class jpsgcs.thold.AnyOldClass with modifiers "public static"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
at java.lang.reflect.Method.invoke(Method.java:490)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:672)
at org.apache.spark.deploy.SparkSubmit$.doRunMain(SparkSubmit.scala:180)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:205)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:120)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
您需要 class public
。默认情况下 classes 是包范围,这意味着它必须驻留在与 org.apache.spark.deploy.SparkSubmit
相同的包中才能调用其方法。
改变
class AnyOldClass implements Serializable {
到
public class AnyOldClass implements Serializable {