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?
Pourriez-vous vérifier que classloaders charge les 2 classes – jrtapsell
De stacktrace, semble être URLClassLoader. – tribbloid
Sont-ils le même classloader? – jrtapsell