You create a new ClassWriter
object, passing in nothing relevant (a settings value, that's all). You then invoke toByteArray
on it. Using 5 seconds to think it through, you should draw the conclusion that this cannot possibly work. The actual class content you'd want to write cannot possibly be known by the classWriter instance you just made - nothing in that code flow provides it to this ClassWriter instance.
The linked code is of highly dubious quality. For example, it leaks the jar file as a resource (it isn't properly resource-guarded). It uses old API (File
) with new concepts (.stream()
), in fairly silly ways. It does the old 'catch an exception, run e.printStackTrace()
, keep going' shtick, which is extremely bad code practice. Its presence in a bare-bones example is suspect; its presence in an example that is clearly intended to be ready to go is inexcusable). It involves outdated third party deps (IOUtils
) that aren't actually needed, especially considering that this code wouldn't compile on anything less than java8, so clearly 'at least java 8' is fair game for this example.
And then, finally, yes, the thing you zoomed in on: That ClassWriter code. Which is just broken.
I think it's best to forget about this blog post. It's beyond saving.
Okay, so how DO I do this?
Well, you've started out by conflating two completely unrelated things 'write a jar file' and 'produce the byte content of a class file' are unrelated, so don't mix em up. You have 2 separate jobs, so write code that does job 1, and test that. Then write code that does job 2, and test that. Then write code that uses the code you wrote for job 1 and 2 and test that, and voila.
How do I write into an existing jar?
You don't. Not how it works. You make a new one. If you really need to, once you're done, you'd use Files.move
to copy/move it 'over' the old one, thus effectively 'replacing it'.
How do I make a new jar?
new JarOutputStream
for example. Check this SO answer for some insights on how.
How do I feed the API of JarOutputStream given an ASM node?
As for example this tutorial shows, ASM isn't so much an 'edit classes in place' kinda tool, it's an 'edit classes in transit' kinda tool. You make a reader which does nothing by itself, you then pile onto the reader various visitors that transform nodes as they are processed, you then hook this all up to a writer and hit the go button. Part of the point is that ASM may not even hold the entire class file in memory.
After making the class writer, you're supposed to invoke all sorts of methods on the classwriter to actually 'write' the class file. You 'write' the basic stats such as the class's name and the like, then you 'write' fields, methods, initializers, and so on.
If you want to write based on an existing class (i.e. transform something that already exists instead of making a class file from scratch), you'd make a reader, and transform as you go. That tutorial I linked shows how to do this.