Определение классов с использованием Unsafe.defineClass без разрешения зависимостей - PullRequest
1 голос
/ 10 февраля 2020

Из-за требований моей программы я нахожусь в ситуации, когда мне нужно определить несколько классов во время выполнения с загрузчиком классов, равным нулю (bootstrap загрузчик классов).

Это обычно очень легко используя что-то вроде

unsafe.defineClass(name, bytes, 0, bytes.length, null, null);

Это, однако, не работает, если мне нужно определить, скажем, 5 разных классов, каждый со ссылками друг на друга. JVM пытается разрешить эти классы до того, как они были определены, что приводит к NoClassDefFoundError.

Есть ли способ предотвратить разрешение классов JVM, когда я определяю их с unsafe.defineClass?

Если нет, возможно, есть способ сделать это с помощью JNI?

Этот вопрос похож на на этот , однако предоставленные ответы не подходят, так как он включает определение классов под ненулевым загрузчиком классов.

1 Ответ

2 голосов
/ 10 февраля 2020

Unsafe.defineClass не разрешает классы, как указано в JVMS §5.4.3 . Большинство символьных c ссылок в константном пуле остаются нерешенными.

Единственными зависимостями, которые должны быть удовлетворены во время определения класса, являются

  1. список реализованных интерфейсов;
  2. суперкласс.

Любой допустимый набор классов можно упорядочить таким образом, чтобы

  • для любого определяемого класса или интерфейса C, все интерфейсы C реализации уже определены ранее, и суперкласс C также определен ранее.

Это означает, что можно определять классы один за другим, если все сделано в правильном порядке. , Вышеупомянутое условие не выполняется только в случае циклического наследования (которое в любом случае недопустимо).

Но убедитесь, что не инициализирует классы и не вызывает иное разрешение классов, пока все указанные классы определены .

...