Often when discussing OSGi at events, conferences or forums, we hear things like, “Yeah, I like JRebel but now we are using OSGi”, or “Does JRebel support OSGi”, or “Isn’t OSGi the same as JRebel?”. Sometimes it happens that people start comparing OSGi to JRebel, which is kind of like comparing a Ferrari to a Skyscaper; thus, this article is designed to a) explain the differences on a technical level what JRebel and OSGi do, b) outline some ideal use cases for OSGi and JRebel c) clear up any grey areas or misconceptions between the two technologies. So, let’s go!
What is JRebel and what is OSGi?
OSGi is a module system and a dynamic runtime where modules (also called bundles) can come and go, but your code has to conform to the requirements of the module system — it is perhaps the only widely used framework for the JVM that enforces real modularity.
In plain speech: OSGi projects are inherently more modular than plain Java projects, as long as you follow the rules — for example, to use classes from another module, that module needs to declare that it exports the packages containing those classes.
If JRebel and OSGi are so different, why do people compare them?
Probably because both JRebel and OSGi are capable of fast or instant class reloading during development. However, with JRebel this is the pure goal, whereas with OSGi this is more of a side-effect. In the end, using OSGi means switching to a brand new framework, while JRebel quickly plugs in to your existing stack.
JRebel instantly reloads changes you make to class structures (e.g. adding/changing/removing methods, constructors, fields, classes, annotations, static field values, interfaces, etc.) so that you see immediately what your code changes look like, regardless of IDE, application server or frameworks.
In OSGi, modules can, in certain cases, be stopped, reloaded and started again with hardly any noticeable downtime. But if that module has dependent modules, this will cause a cascade effect of reloads. (JRebel monitors all of the code in your workspace and automatically reloads changes to it in less than 1 second)
What should I know about OSGi?
OSGi is the most well-known system for enforcing modularity on the JVM — tools like PDE and BndTools will validate the module boundaries and their dependencies as you edit, and your code will not run under an OSGi runtime if it tries to ignore the boundaries.
The OSGi Alliance claims that the 11-year-old framework and the enforced modularity will yield benefits such as ease of component reuse, reduced complexity (if your system already has complex dependencies), ease of deployment, dynamic updates, resilience to change, proper versioning, escape from JAR hell, simplicity etc.
Some of these claims are facts, but may or may not apply to your specific case. Others can be debated, and people have. There are both success stories and not-so-awesome stories about implementing OSGi.
It increases modularity and dynamism
OSGi can benefit your project under the following circumstances:
- You want more modularity because you have:
- a complex set of dependencies
- lots of reusable pieces
- customizations of your software in different contexts
- a chaotic mess of a system that needs some order introduced into it
- You want more dynamism because:
- you want to be able to install and uninstall services or plug-ins into a running system
Not every system meets the description, and if you don’t feel the need for any of it, it’s unclear whether OSGi will help you or actually introduce more complexity than it removes. Of course, each individual case is different.
It can dynamically reload changes
Because the OSGi runtime is dynamic, where bundles can be installed, started, stopped and uninstalled, it is possible in some cases to simply stop a module, reload it, and start it again. Of course, if other modules depend on the reloaded module, they will have to be stopped and rewired to the new version as well.
It is perfectly reasonable for some expert users to find that OSGi’s reloading capabilities suit them just fine and don’t need to be complemented by JRebel, but it requires conscious effort to achieve that.
It’s worth considering that if bundles have internal state that is not restored at start-up, reloading them will lose that state. This means that when you’ve filled a form, navigated to a new page and then reload a bundle, you need to take these steps again…and your program state gets nuked during the reload.
OSGi’s runtime is very much based on classloaders – each bundle gets it’s own classloader, with references to classloaders of other bundles – the module’s dependencies. OSGi handles reloading by dropping the entire module classloader and creating a new one – it does not reload single classes or try to preserve their state.
JRebel has a lot to do with classloaders as well – it hooks into existing classloaders to make the classes loaded through them instantly reloadable (while maintaining state), and this works with or without OSGi.
So can I use JRebel and OSGi together?
OSGi and JRebel are not directly comparable nor competing with each other. There is a small overlap as both allow some form of reloading code in a running application, but for most uses of OSGi that is a side effect more than a goal. For JRebel, it’s the main feature.
JRebel does support reloading in OSGi applications, so there is a way to use both together. Ideally, you could let JRebel reload most changes to code in a bundle, and let OSGi reload the entire bundle if changes become larger e.g. if a dependency was added, or the bundle’s activation sequence was modified.
We’ve already seen that OSGi is concerned with your application’s architecture as well as design, and requires both effort on your part and a whole ecosystem around it – you can’t use third-party libraries unless they have been „osgified“ either by the original library developers, someone else, or you.
JRebel doesn’t concern itself with modules, and is meant to be transparent. It is a single plugin that tries to stay out of your way and make Java as fast as a scripting language. JRebel is only concerned with reloading your code and static resources, whatever existing Java technologies you are using — you don’t need to change anything about the way you and your team is developing.
With JRebel, you only need to spend a few seconds providing a mapping from your running application to resources in your workspace, where the changes are made during development. And even this mapping can be generated by Maven or IDE plug-ins in most cases.
What should I take away from this?
To put it bluntly, implementing OSGi should be done when the end goal is to achieve modularity and dynamism, but this requires continuous effort on your part; using JRebel is about increasing productivity by making Java as fast and iterative as Python, PHP or Ruby. It just requires download and pressing a couple of buttons in your IDE.
Perhaps you shouldn’t go for OSGi in a new project if all you expect to gain is increased productivity through quick code reloads. OSGi is made for projects that require a highly modular architecture. Regardless of your needs, JRebel can help you in either case.