This was asked 8 years ago here and since then 8 years have passed. I wanted to ask this question again to see if anyone has developed a framework, tool or library that does monkey patching.
Basically what I need it for is a java application that I applied my own patch to. Since this project is maintained by another team I want to be able to keep/apply any patch I make, to the patches they make.
There are a number of techniques that might be applicable here, but your question is too vague to narrow them down to a single answer.
"Monkey patching" in the literal sense that it is used in Ruby (i.e. "replace methods of a class at runtime", see e.g. [1]) is possible with "Java Agents" and the "retransform" API, but it's much harder than it is in Ruby.
I need it for a java application that I applied my own patch to
If there is an app for which you have the source code, say in git
, then you could fork their project, apply your own patch and build a modified version.
I want to be able to keep apply any patch I make, to the patches they make.
If you create your patch on a branch then it will be easy with git
to pull in any future changes from the "upstream" project into your branch, and build a new modified version.
An easy technique that more closely approximates Monkey Patching is to compile a single class from the target app, with modifications, and put it earlier on your classpath than the original JAR. (This is covered in the old Monkey Patching q at this answer: https://stackoverflow.com/a/381240/8261 )
The JVM loads all classes by name, and will use the first classfile it finds on the classpath for any class, so you can replace the classes one-by-one from the project you wish to modify. If you have the source for the target project, then copy that into your app file-by-file and then apply your patches to the java source.
(You will need to manually apply any future upstream changes with this approach.)
The JVM has an API called "Java Agents" which lets you register code to modify classes at the time they are loaded.
There is also a "retransform" API that lets you change the definition of already loaded classes. This is used by JRebel to update code in running applications. It's much more limited that Ruby's monkey patching in that you can't add or remove methods (you can change method bodies).
This mechanism is used by https://github.com/fommil/class-monkey to "monkey patch" a JVM bug, for example.