Im looking to use ASM to modify a running jar file and wanted to ask some questions. First with ASM can I 'live' edit and what I mean is, can I edit a jar which is currently being run e.g. a game and then inject my code into the jars class files and have it stick untill the jar is closed? So it will still be called in the games run loop etc? As from what I've tryed I can only get my code to run the once... Thanks
3 Answers
Take a look at the java.lang.instrument package. You could write a Java agent that registers a ClassFileTransformer.
The transformer can use ASM to process bytecode from class files, transform them to what you want, and return the new bytecode from ASM. There's also potential for modifying class files after they have already been loaded, but this can be a bit hit-and-miss as you have to make sure not to change signatures, etc.

- 22,460
- 3
- 73
- 80
You should hack that jar's ClassLoader as well
and return the the modified Class when findClass is called

- 7,816
- 3
- 30
- 26
You can use reflections to change code behavior in runtime. It will not stay in the "jar", and at least while the classes you need are loaded, all will be well.
You need to, then, provide the mechanism to inject your changes using reflections in your program. Or that's the way I'd go about it, anyway.
Furthermore: the answer to this question has even more flexible options for runtime modding. If you use its third option, you can code in javascript (or other languages) (related info, a blog dedicated to scripting in java) using the facilities defined in JSR-223.
-
1@iajrz Are you saying that you can modify code with the reflection API? Please clarify because as it stands, your answer appears to be wrong. – Charles Forsythe Nov 06 '13 at 12:53
-
You can modify the behavior in runtime, which is what the asker needs... he doesn't need to store it, so he doesn't really need to modify the bytecode. If the proper hooks are placed, it is possible to substantially modify the behavior of code. For instance: you have a method which checks on some externally modifiable condition and calls a different method depending on it; If you do this in certain (although delicate) ways, you could have the method change it's behavior completely given interaction with the enviroment. – iajrz Nov 06 '13 at 13:41
-
I had to do that for a webservice a couple of years ago, to avoid revisiting the same code every month: depending on the SOAP request, a different class could be instanced and a method called. But the class, method and arguments changed. So we built a proxy which behaved substantially different depending on the request contents. – iajrz Nov 06 '13 at 13:43
-
@CharlesForsythe, thanks for the questioning; my wording was vague. Fixed that and expanded the answer... I think we all win from this. – iajrz Nov 06 '13 at 13:59
-
@iajrz The key here is "the proper hooks." The OP does not indicate that he has access to the target code in which to place "hooks." If you need to change the behavior of arbitrary code at runtime, the reflect API will get you nowhere. Also, modifying byte code has _nothing_ to do with storing it anywhere. You can modify byte code in an agent or class loader at runtime and just have the modified bytecode run memory. – Charles Forsythe Nov 06 '13 at 14:05
-
Agreed, didn't indicate the access to the target code. But I didn't mislead: I specifically stated that the hooks are needed. And the storing I mentioned because the OP specifically wanted to have things run differently only once, ie: not modify any jar files. Would you kill a cocroach with a gun? If you can do with reflections, why add an external dependency? – iajrz Nov 06 '13 at 14:10
-
The OP wants to "modify a running jar file". You can't do that with reflection. Period. You are confusing "modifying behavior at runtime" with "coding for dynamic behavior" which are two entirely different things. I'm going to have to downvote your answer because it does not actually address the question. – Charles Forsythe Nov 06 '13 at 14:24
-
let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/40642/discussion-between-iajrz-and-charles-forsythe) – iajrz Nov 06 '13 at 14:29
-
1. My corporate firewall blocks access to chat. 2. I'm not changing my mind. If you don't like my vote, take it up with the moderators. – Charles Forsythe Nov 06 '13 at 14:31
-
Ah, ok... I can post it here: I imply ownership of the code from the first answer: place the hooks, provide the mechanisms... if the OP isn't owner of the code, why choose this useless answer? I may have misinterpreted the question-- you have a point, he states "a running jar". But when you build your java project, do you not produce a running jar? And can you not modify its behavior through Reflections? – iajrz Nov 06 '13 at 14:32
-
I don't like your vote, only because the OP's choosing the answer kind of makes it seem relevant to the question. But I admit there's ambiguity, so... I don't really mind your vote. It's helpful for people who come looking for what you interpreted the OP is looking for, not what I interpreted the OP is looking for. – iajrz Nov 06 '13 at 14:34