Почему я не могу получить доступ к закрытому пакету в другом банке (НЕ запечатанном)?
Я столкнулся со странным поведением загрузчика классов Java:
Предполагая, что я отправляю jar Apache Spark в кластер, который содержит расширение 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, когда кластер настроен. Затем мой класс (в другой банке) загружается той же JVM, когда мое заявление подано.
В этот момент я получил следующую ошибку:
Исключение в потоке "main" java.lang.IllegalAccessError: класс org.apache.hive.service.server.DPServerOptionsProcessor не может получить доступ к своему суперклассу org.apache.hive.service.server.HiveServer2$ServerOptionsProcessor в java.lang.ClassLoader.define Собственный метод) в java.lang.ClassLoader.defineClass(ClassLoader.java:763) в java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) в java.net.URLClassLoader.defineClass(URLClassLoader) jj..net.URLClassLoader.access$100(URLClassLoader.java:73) в java.net.URLClassLoader$1.run(URLClassLoader.java:368) в java.net.URLClassLoader$1.run(URLClassLoader.java:362) в java.security.AccessController.doPrivileged(собственный метод) в java.net.URLClassLoader.findClass(URLClassLoader.java:361) в java.lang.ClassLoader.loadClass(ClassLoader.java:424) в java.lang.ClassLoader.aderClassjo Class:357) в org.apache.spark.sql.hive.thriftserver.DPHiveThriftServer2$.main(DPHiveThriftServer2.scala:26) в org.apache.spark.sql.hive.thriftserver.DPHiveThriftServer2.main(DPHiveThriftServer2.scala) в sun.reflect.NativeMethodAccessorImpl.invoke0(нативный метод) в sun.reflect.NativeMethodAccessorImpl.incej.jpg DelegatingMethodAccessorImpl.java:43) в java.lang.reflect.Method.invoke(Method.java:498) в org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:731) в org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:181) в 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)
У меня сложилось впечатление, что класс private-package может быть доступен любому другому классу в том же пакете. И я дважды проверил файлы манифеста в jar-файлах Spark, и ни один из них не объявил org.apache.hive.service.server как запечатанный пакет. Так почему загрузчик классов JVM дал мне эту ошибку? Какое условие JVM использовала, чтобы вызвать исключение?
1 ответ
Поскольку 2 пакета загружаются разными ClassLoaders, они рассматриваются как 2 разных пакета, поэтому это означает, что закрытый метод пакета недоступен, что приводит к сообщению об ошибке