Inside the burrow: a JRebel deep dive
So here we are again, at the beginning of a new JRebel deep dive article. In the previous article, we dove right into class loaders. What are they, what drives them and what do they aspire to be? No worries if you can’t quite remember the details. You can always take a sneak peek at the article, I had to do this as well! When you are ready, grab yourself a cup of tea or coffee and let’s start with the second part of the deep dive on how JRebel, and the technologies behind it, works!
What was happening again?
Are you ready? Alright, let’s start with the next part of the “How does JRebel work” article. The paragraph we’ll be focusing on this time goes like this:
When a class is loaded JRebel will try to find a corresponding .class file for it. It will search from the classpath (including an application classpath, like WEB-INF/classes) and from the places specified in the rebel.xml configuration file. If it finds a .class file JRebel instruments the loaded class and associates it with the found .class file. The .class file timestamp is then monitored for changes in the loaded class and updates are propagated through the extended class loader, to your application.
Alright that makes more sense now than it did a couple of weeks ago. When a class is loaded by the JRebel extended class loader (remember?), this class loader will look for the .class file and do everything that you read in quote.
What piques my interest, is the small part where JRebel instruments the class loader. What does JRebel do with the loaded class and what happens during this instrumentation? The last part of the quote is also straightforward, the .class file is monitored for changes so if I want to see my changes in my running application, I will have to compile the Java files that I changed.
Let’s start digging
Now that we got that down, I would like to focus on what JRebel does for magic tricks in order to instrument the loaded classes. Perhaps it is wise to first get an idea on how dynamic class loading could work? It’s always useful to have a basic understanding of a subject before diving in to deep. Luckily, the fine folks at JRebel already posted about how you can dynamically change classes. The gist of the article is that it is rather simple to create a dynamic classloader. Really, just read the article, the author creates a simple example which you can follow yourself!
The tough part about creating dynamic classloaders is that you still want to preserve the current state of objects that where already created. This sounds logical because otherwise you could get some funky results during runtime. To preserve the state of the class, you would need to manage the state of the classes by hand during (or just after) the instantiation of the classes.
The problem is, we can only use this trick on objects that are being instantiated! Only then are we capable of initializing an object with the new class code and copying all data from the old object to the new one. Unfortunately, we also must consider the objects that were already loaded and are floating around in the JVM. We would like that these objects use the new class code as well!
Disclaimer: I’m aware that the above-mentioned article “How to Use Java Class Loaders” was written in 2009 and that this is a long time ago in technology terms. However, I still would like to mention the article since I think that it gives a brief overview of what happens in JRebel even though it might not be 100 percent accurate anymore. There was also a rewrite of the article with extra information which you can find here. But for now, I’ll be focusing on the older article because I find it clearer.
Did we hit a rock?
Now that I know this, perhaps I could try to find out what happens exactly with the classes that were already loaded? I don’t think it will be easy to find an answer because this seems to me the reason why you would buy JRebel. This would be were the real magic happens. Maybe I’m wrong but that’s my view on the situation at least. I assume it will take some more digging in order to find out what is happening with the already loaded object.
Luckily, I did find another article about our subject! After reading the article, I didn’t really get the answers I was hoping for. However, I did give me some more breadcrumbs that I could follow. The article mentions the use of abstract bytecode in combination with classloaders in order to get the necessary results.
So, for the next article(s), I would like to focus on that and see where this leads me. Hopefully not too far from our goal but we can try to dig around the rock and if that doesn’t work out, we can turn around and look for another approach.
And as always, if you have any questions after reading this or perhaps have some remarks. Feel free to contact us at firstname.lastname@example.org or via the button on the site!