Reputation: 21
I have a java template class, of which I would like to modify a single String field. I can instantiate an object of that class, get to its corresponding Class object, and modify the field using reflection, so far so good. But how do I actually save the bytecode to the filesystem?
Since I think that if I get to the ClassLoader of the original template class, get to the InputStream and try to save to a file I will get the original (i.e. unmodified) class implementation. Is it so?
Ideally I would also need to change the class name to something more meaningful.
Can both things be done using pure java in the first place? Or do I have to resort to external libraries?
Upvotes: 1
Views: 449
Reputation: 13535
Find an assembler/disassembler pair. Disassemble the class file, replace the string value, and compile back to class file. Note that the string constant can be referenced from several points, so probably you have to add a constant and change only one reference. If the new string value has the same length as the old one (in UTF-8 encoding), then you just replace constant with a binary file editor. If length are different, replacing would destroy the whole classfile structure.
Upvotes: 0
Reputation: 39451
When you modify a field using reflection, you're not changing anything about the class itself. It's just a fancy way of setting a variable. So there's no changed bytecode to worry about in the first place.
Anyway, AFAIK you can't easily get access to bytecode at runtime. The JVM creates classes from classfiles (either from files or in memory data) but once the class is loaded, there's no particular reason to keep the data around. Most likely, it will only keep an optimized representation that doesn't necessary correspond to the original classfile.
I think there are some APIs like Java agent that deal with bytecode at runtime, but it's not clear how well they work, partly because the JVM does optimize things.
Upvotes: 4