2017-09-09 2 views
0

J'ai rencontre un comportement étrange de Java classloader:Pourquoi je ne peux pas accéder à une classe privée dans un autre pot (NON scellé)?

En supposant que je soumets un pot Spark Apache à un cluster, qui contient une extension de HiveServer2:

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

La classe HiveServer2.ServerOptionsProcessor est déjà préchargé sur le cluster (en tant que dépendance Spark), mais déclaré comme étant privé-package.

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

    static interface ServerOptionsExecutor { 
    ... 
    } 
} 

Cette classe est chargée en premier lieu par la JVM lorsque le cluster est configuré. Ensuite, ma classe (dans un autre pot) est chargée par la même JVM lorsque ma demande est soumise.

À ce stade, j'ai eu l'erreur suivante:

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)

Je suis sous l'impression que la classe de package-privé est accessible par une autre classe dans le même paquet. Et j'ai vérifié les fichiers manifestes dans les fichiers JAR de Spark, aucun d'entre eux ne déclare org.apache.hive.service.server en tant que paquet scellé. Alors pourquoi le classloader JVM m'a-t-il donné cette erreur? Quelle condition JVM a-t-elle utilisée pour déclencher l'exception?

+0

Pourriez-vous vérifier que classloaders charge les 2 classes – jrtapsell

+0

De stacktrace, semble être URLClassLoader. – tribbloid

+0

Sont-ils le même classloader? – jrtapsell

Répondre

1

Comme les 2 paquets sont chargés par différents classloaders ils sont traités comme 2 paquets différents, donc cela signifie que le paquet méthode privée n'est pas accessible, ce qui dans le message d'erreur

More Info