Я создаю несколько классов ByteBuddy (используя DynamicTypeBuilder
) и загружаю их. Создание этих классов и их загрузка происходит в одном потоке (главном потоке; я сам не создаю никаких потоков и ничего не отправляю в ExecutorService
) в относительно простой последовательности.
Я заметил, что выполнение этого в модульном тесте несколько раз подряд дает разные результаты. Иногда классы создаются и загружаются нормально. В других случаях я получаю ошибки из сгенерированного байт-кода, когда он впоследствии используется (часто в общей области, где я использую withArgumentArrayElements
, если это важно; ArrayIndexOutOfBoundsErrors
и тому подобное; опять же, в других случаях все это работает нормально (с теми же входами)).
Это похоже на состояние гонки, но, как я уже сказал, я не создаю никаких тем. Поскольку я не использую потоки, их может использовать только ByteBuddy (или JDK). Я не уверен, где это будет. Есть ли механизм синхронизации ByteBuddy, который я должен использовать при создании и загрузке классов с DynamicTypeBuilder.make()
и getLoaded()
? Возможно, какое-то разрешение класса происходит (или не происходит!) в фоновом потоке или что-то в make()
время, и я случайно каким-то образом препятствую его завершению? Возможно, если я собираюсь использовать эти классы немедленно (я), мне нужно предоставить другой TypeResolutionStrategy
? Я сбит с толку, и это должно быть ясно, и я не могу понять, почему однопоточная программа с одними и теми же входными данными должна создавать сгенерированные классы, которые ведут себя по-разному от запуска к запуску.
Мой шаблон для загрузки этих классов:
- Попробуйте загрузить (обычно несуществующий) класс, используя
Class#forName(name, true, Thread.currentThread().getContextClassLoader())
. - Если (когда) это не удается, создайте класс, сгенерированный ByteBuddy, и загрузите его, используя обычные рецепты ByteBuddy.
- Если это не удастся, то только потому, что какой-то другой поток мог уже создать класс. В этом модульном тесте нет другого потока. В любом случае, если здесь произойдет сбой, я повторяю шаг 1, а затем выдаю исключение, если загрузка не удалась.
Есть ли какие-либо шаги, специфичные для ByteBuddy, которые я должен предпринять в дополнение к этим или вместо них?
ArrayIndexOutOfBoundsException
с другим, в настоящее время мне не понятно. - person Laird Nelson   schedule 09.09.2020