My point is, if you don't understand the abstraction of a framework, you can still decompile it and understand it, because you know the language e.g. Java. However, when byte-code generation happens, you have to understand even a lower level - JVM level byte-codes. I am really affraid of using any of such frameworks, which are many. Most of the time I think the reason for byte-code generation is simply lack of language features such as metaprogramming. Do you agree? What is your opinion and argument? How do you take over the problem with leaky abstractions in those frameworks?
Simple answer first: use these frameworks carefully, not every and not too many.
You are correct in your assumption that byte-code generation is usually about working around language limitations e.g. dependency injection. Fixing these limitations provides powerful tools (spring, guice, hibernate) but when it comes down to it it is no longer pure Java (still pure JVM) and thus comes with a bit of magic. As long as you use only one of these tools you are probably ok in not looking too deep into the internals. But if you start mixing them you need to understand a bit more of them. The only helping factor is previous use; if other people have successfully integrated more of these frameworks and documented it you might get away with not looking too deep.
When you want to use some tool ask yourself:
- What do I gain ?
- Does it work with my other tools?
- Could I use a simpler tool ?
Every time you add a tool you add complexity. Every time you add a complex tool (e.g. with byte-code generation) you multiply complexity.
Examples:
at work we use spring + hibernate. This is an improvement over EJBs ( < v3) and the combination is well known to work and well documented.
in a toy project I use Guice. This makes some decouplings possible but requires every user of my libs to use Guice. For that reason I might through Guice out.