0

我遇到了 Java 类加载器的奇怪行为:

假设我向集群提交了一个 Apache Spark jar,其中包含 HiveServer2 的扩展:

package org.apache.hive.service.server;
public class MyOP2 extends HiveServer2.ServerOptionsProcessor(
  String var) {
...

HiveServer2.ServerOptionsProcessor 类已经预加载到集群上(作为 Spark 依赖项),但被声明为包私有。

package org.apache.hive.service.server;
public class HiveServer2 extends CompositeService {
...

  static interface ServerOptionsExecutor {
  ...
  }
}

设置集群时,此类首先加载到 JVM。然后,当我的应用程序提交时,我的类(在另一个 jar 中)由同一个 JVM 加载。

此时我收到以下错误:

线程“主”java.lang.IllegalAccessError 中的异常:类 org.apache.hive.service.server.DPServerOptionsProcessor 无法在 java.lang.ClassLoader.defineClass1 访问其超类 org.apache.hive.service.server.HiveServer2$ServerOptionsProcessor( Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:763) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) at java .net.URLClassLoader.access$100(URLClassLoader.java:73) at java.net.URLClassLoader$1.run(URLClassLoader.java:368) at java.net.URLClassLoader$1.run(URLClassLoader.java:362) at java.security .AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:361) at java.lang.ClassLoader。loadClass(ClassLoader.java:424) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at org.apache.spark.sql.hive.thriftserver.DPHiveThriftServer2$.main(DPHiveThriftServer2.scala:26) at org. apache.spark.sql.hive.thriftserver.DPHiveThriftServer2.main(DPHiveThriftServer2.scala) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect。 DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$ runMain(SparkSubmit.scala:731) at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:181) at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:206) 在 org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:121) 在 org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)

我的印象是包私有类可以被同一个包中的任何其他类访问。而且我已经仔细检查了 Spark 罐子中的清单文件,它们都没有将 org.apache.hive.service.server 声明为密封包。那么为什么 JVM 类加载器给了我这个错误呢?JVM 使用什么条件触发异常?

4

1 回答 1

3

由于 2 个包由不同的 ClassLoader 加载,因此它们被视为 2 个不同的包,因此这意味着无法访问包私有方法,从而导致错误消息

更多信息

于 2017-09-12T14:53:18.247 回答