Create Simple Pojo Classes (Bytecode) at Runtime (Dynamically)

How to create and then instantiate POJO classes dynamically?

You can use reflection to instantiate the generated classses and access the provided methods.

Create Pojo at runtime and after saving pojo on to the disk throwing an error as class pruned?

When looking at the source code, it seems, that the problem is caused by the fact that both, wasChanged and pruned, are true.

Actually, automatic pruning should be off by default, at least on recent versions. But if the class file has been pruned, it should not allow subsequent modifications. This leads to the conclusion that you can’t have modified the CtClass object in-between, so the error is not on your side. Searching for occurrences of wasChanged in the file reveals that it has been forgotten to ever set it to false.

So what happens, is

  • You set up the class under construction, which turns wasChanged to true.
  • You call toClass(), which in turn invokes toBytecode, which will set pruned and frozen to true, disallowing further modifications, but forgets to set wasChanged to false.
  • You call writeFile, which will also call toBytecode, which now detects that the file has been modified, according to the flag that it never resets, and throws an exception, as the class has been pruned.

If you swap toClass() and writeFile, the logic stays the same, as it is the fact that both call toBytecode internally, which can’t be invoked twice, given the behavior described above.

You have several options.

  • You can call debugWriteFile​(path) before calling toClass(), as debugWriteFile is documented to “not prune or freeze the class after writing the class file”.

  • You can call stopPruning(true) before calling writeFile or toClass. As mentioned above, pruning should be even off by default.

  • You may call toBytecode() directly yourself and call it only once. Then…

    • Once you have the byte array, you can simply write it to a file (e.g. Files.write(Paths.get(pathString), byteArray).

    • To use this existing byte array to create the class, you may use your own class loader or use MethodHandles.lookup().defineClass(array), if you are under Java 9 or newer and create a class in your own package.

    This might be a bit more complicated, but since this constructs the class file bytes only once, it’s the most efficient solution.



Related Topics



Leave a reply



Submit