2017-09-09 42 views
0

我已经遇到的Java类加载器的一个奇怪的现象:为什么我不能在另一个jar(不密封)中访问一个包私有类?

假设我提出一个Apache星火罐子到集群,其中包含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加载。

在这一点上,我得到了以下错误:

Exception in thread "main" java.lang.IllegalAccessError: class org.apache.hive.service.server.DPServerOptionsProcessor cannot access its superclass org.apache.hive.service.server.HiveServer2$ServerOptionsProcessor at java.lang.ClassLoader.defineClass1(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) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at 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) at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:121) at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)

我的印象是包私有类可以通过任何其他类在同一个包可以访问下。我已经在Spark的jar中检查了清单文件,他们都没有将org.apache.hive.service.server声明为密封包。那么为什么JVM classloader给了我这个错误? JVM用于触发异常的条件是什么?

+0

你能检查哪些类加载器加载2个类 – jrtapsell

+0

来自stacktrace,似乎是普通的旧URLClassLoader。 – tribbloid

+0

他们是同一个类加载器吗? – jrtapsell

回答

1

作为2包被它们被视为2个不同的包不同的类加载器加载的,因此这意味着该包专用方法是不可访问的,从而导致错误消息

More Info

相关问题