Down the rabbit hole: a JRebel deep dive
We’ve all been there; we sit behind our desk thinking to ourselves “Well, here we go again” as you press the button to build your code so you can deploy the latest version to your local server. From there on it really does take a couple of minutes before you can go back to work with testing your code.
Of course, during that time I usually tell myself that I can do some other tasks in the meantime. I read my user story again to make sure that I got the right acceptance criteria in my head. Perhaps I can check a couple of pull requests? Or maybe even help test a couple of smaller stories while I’m waiting on my application server which is booting because, you know, it’s Friday for everyone and even my server is taking its time.
JRebel to the rescue
But then I remembered! I heard a couple of senior developers talk about what sounded like some magical technology that builds my code and automagically replaces the old code with the new code without shutting down the application server. Of course, I know it isn’t magical, but I don’t know what it does, so it sounds quite magical to me. So, I created a task for myself. To check out what this technology is and what it does and write it down for people that are in a similar situation. With that I started talking to some colleagues about it and they pointed me in the right direction. They said they use JRebel for the task. That’s at least a good place to start my journey.
I’m realistic. This won’t fit in one blog post and I’ll have to divvy up the post in some logical places in order to keep myself focused and so that I can give the proper attention to all the different aspects. So, consider this the intro to a series of posts about the JVM, hot swapping, JRebel, DCEVM and many more. Again, the focus lies on explaining the magic behind some technologies: What does it do? how does it work? But also figuring out the basics behind simple java programming.
And the adventure begins
Well, I guess I’m going on an adventure but first I need to find some sort of map which I can follow. I think the best map would be “How does JRebel work” because after all it is the technology I would like to understand. So, let’s dive into the rabbit hole and start with first paragraph:
JRebel integrates with the JVM and application servers mainly on the class loader level. It does not create any new class loaders, instead, it extends the existing ones with the ability to manage reloaded classes.
Alright that is a good start. This gives me a general direction to walk in. I know what the Java Virtual Machine (JVM) is and I’ve heard of class loaders. But now I’m wondering: what are class loaders actually? What do they do? And how are classes loaded into the JVM?
During my research, I found that there are some changes in Java 9 concerning class loading but for now I will focus on class loading in Java 8 because that is the version I’m predominantly working with and I have to start somewhere. Perhaps, I will write a separate blog on changes made to class loading in Java 9 once I have this blog post finished.
Hello, class loading
Let’s create a generic hello world program and start from there. We open an editor or IDE, create a .java file, write the famous code and compile the .java into a .class file with javac. Now we have a file with our code compiled to Java byte code which can be executed on the JVM. We run the java command and voila our code runs. But what happens when you execute the command?
Well, you start a whole chain of events! Starting with the creation of a new JVM. Once the JVM is started, following the specifications, it will start loading, linking and initializing files. Starting from the entry point (you know the main() method) the JVM starts loading all classes and that’s the part we’re interested in right now.
Loading, loading, loading, …
During the loading step the JVM uses, as you might have guessed, class loaders to load class information into the heap. It will do so following a delegation model: load requests are first passed to the System Class Loader/Application Class Loader. Unless you defined your own custom class loaders, but we won’t look at those for now.
When the System Class Loader receives the request, it will look in its caches and if it doesn’t find an answer there, the loader will pass the request to its parent which will do the same. All the way to the Bootstrap Class Loader. You can see this in the figure below. If the parent doesn’t find the class, it will be passed back to the child which will check its own path and if necessary, will pass the request back down to its child class loader as well. It’s a recursively and depth first search which ends in the Bootstrap Class Loader. If none of the class loaders find the necessary .class file a NoClassDefFoundError or ClassNotFoundException will be thrown.
Let’s back up
Let’s look back at our HelloWorld example. Once you run java, the JVM starts and requests our HelloWorld class and all dependencies of that class. Even though it doesn’t look that way, our simple example has quite a few dependencies. Our program would need String and all its dependencies, System and all its dependencies and so on. I think you get the gist of it.
All these requests will be passed from to the System Class loader to the Extension Class loader and eventually to the Bootstrap Class loader which will find a fair bit of the required classes in the rt.jar located in your JAVAHOME. Tip: you can check what is loaded and from where if you use the verbose:class parameter together with the java command.
After the loading step, all necessary information will be loaded in the heap and the linking/initializing steps can start. For now, I think this is enough of information. We at least now know what class loaders are and what they do. I’ll have to let this information sink in for a while and start writing on the next part in the series where I’ll have a look at what information is stored in the heap because I have a feeling that it might be important to know.
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!