При взгляде на исходный код кажется, что проблема вызвана тем, что оба значения, wasChanged
и pruned
, true
.
.
На самом деле автоматическое сокращение должно быть отключено по умолчанию, по крайней мере, в последних версиях. Но если файл класса был удален, он не должен позволять последующие изменения. Это приводит к выводу, что вы не могли изменить промежуточный объект CtClass
, поэтому ошибка не на вашей стороне. Поиск в файле wasChanged
вхождений обнаруживает, что когда-либо было забыто установить для него значение false
.
Так что же происходит,
- Вы устанавливаете строящийся класс, который превращает
wasChanged
в true
.
- Вы вызываете
toClass()
, который, в свою очередь, вызывает toBytecode
, который установит pruned
и frozen
на true
, запрещая дальнейшие изменения, но забывает установить wasChanged
на false
.
- Вы вызываете
writeFile
, который также вызывает toBytecode
, который теперь определяет, что файл был изменен, в соответствии с флагом, который он никогда не сбрасывает, и выдает исключение, так как класс был удален.
Если вы поменяете местами toClass()
и writeFile
, логика останется прежней, так как это тот факт, что оба они вызывают toBytecode
внутри, что не может быть вызвано дважды, учитывая поведение, описанное выше.
У вас есть несколько вариантов.
Вы можете позвонить debugWriteFile(path)
до , позвонив toClass()
, так как debugWriteFile
задокументировано как «не сокращать и не замораживать класс после записи файла класса» .
Вы можете позвонить stopPruning(true)
, прежде чем звонить writeFile
или toClass
. Как упомянуто выше, обрезка должна быть по умолчанию выключена.
Вы можете позвонить toBytecode()
непосредственно себе и позвонить только один раз. Тогда ...
Это может быть немного сложнее, но поскольку это создает байты файла класса только один раз, это наиболее эффективное решение.