OSGi After 20 Years
blog.osgi.org
blog.osgi.org
What OSGi produced is a model to handle dependencies, service lifecycle, and provisioning. But in the Java ecosystem, those features were replaced with a mix and match of smaller projects, that are easier to adopt and use.
Instead of adapting to the community, OSGi frameworks like Eclipse Equinox live on their own island.
Take for example provisioning: Equinox has its own framework called P2. You don't need P2 to use OSGi. But, it's the way of doing things in Equinox. So to share a library, you need to provide packages using a P2 update site. There is no easy way of using Maven Repos [1]. The end result: tons of unnecessary complexity, and more isolation of projects that relies on Equinox tooling [2].
[1]: Tycho is the solution for interacting with Maven repos; but is not easy to setup...and in the end all the trouble doesn't pay: you end with a mix of dependency definitions that is hard to maintain/troubleshoot.
[2]: I'm looking at you SWT... you promise a nice native UIs, but consuming SWTs JARs from a non-Equinox project is a pain... thank you P2 and OSGi! :)
Honestly. Some of the most horrifying systems I have worked with were based on the idea that you should be able to swap implementations during runtime. That was the time when OSGi was the thing and (like mentioned in the article) there seem to be only a few how to use OSGi properly. I'm a burned child and certainly don't have the knowledge, either ...but the blog post doesn't give a single reason to change that.
Frankly, the fact that osgi solved an important problem and people still don't use it indicates a failure, not a success.
Is that in quotes because it's a quote? If so, from where? Or is this a form of emphasis?
I see a similar problem with the common preference for unit tests over integration tests. The mistakes in a system tend to be in the interactions between parts, not in the parts themselves, and by construction, unit tests can't test those.
And it's usually such an unnecessary feature!
There's nothing that makes me fear for a project's future more than when they get to the 'we'll make everything a plugin' phase.
It's statements like that which drive me crazy. It may very well have lower overhead, but even a function call has overhead, and OSGi's overhead is not small (at least last time I used it, circa 2012).
Remember Eclipse? Remember how, once you installed a couple of java plugins, it'd take up to several minutes to start up? All those plugins were OSGi, via the Equinox framework. The overhead was noticeable and severe. Contrast that to IntelliJ, where I have it set up to support a dozen or so languages, all with various plugins, and startup never takes more than 30 seconds. Still not as fast as I'd like, but I shudder to think how Eclipse would manage.
I also echo a lot of the commenters here from the development perspective. OSGi is one of the least pleasant systems I've had to write for. Some of that comes down to Java's questionable approach to dynamic class loading, but OSGi added a ton of cruft and complexity on top of that.
It uses declarative services [2] with annotations to define components and their dependencies. I am not very familiar with the underlaying tooling but the end result is quite simple (see [3] for a simple component with 3 dependencies).
Disclaimer: I work at Liferay.
[1] https://github.com/liferay/liferay-portal
[2] https://osgi.org/specification/osgi.cmpn/7.0.0/service.compo...
[3] https://github.com/liferay/liferay-portal/blob/5c29b7173777b...
https://jcp.org/en/jsr/detail?id=283
This is essentially a hierarchical database - think something like an XML document, a hierarchy of nodes of particular types with attributes according to their type - but has a few really eye-opening features, like versioning, and branching and merging of versions. I'm not aware of any other kind of database (apart from VCSes!) that does that.
Honestly, everyone just re-interprets microservices as whatever they feel like! This particular quote is just describing modularity and encapsulation, something that Parnas could have told them in the '70s.[1]
Microservices are about decoupling teams from each other so they can work and deploy on their own schedule. To a lesser extent, they're about scaling different parts of the system independently (on stacks that don't natively support that with a sane concurrency model). That's really just it. Everything else is hype and buzzwords.
[1] https://blog.acolyer.org/2016/09/05/on-the-criteria-to-be-us...
You can have (micro)services deployed from as single huge codebase - just take a look at all so-called monorepos.
beyond the fact that the world moved from big irons 25 years ago making this whole exercise in in-jvm-microservices pointless, messing with the classloader breaks most of the good things of the Java platform
classloader deadlocks? check
debugger having a stroke trying to use the correct source between all the overlapping libraries at different version within the classloader tree? check
hot code road unable to figure out all the instances of services to replace causing weird class cast exceptions of classes over themselves? check
having to create library projects that include interfaces from independent services because in the OSGi tree you can't have cross dependents? check
I hate the thing with passion and move into real microservices fast enough
I consider it a poor evangelism approach to make me feel stupid and useless. In all honesty I tried to understand OSGi about ten years ago and failed to understand how to get started and how my current project could benefit from this. So we kept using maven and eventually gradle.
It was a nightmare. We were basically forced to use Eclipse (instead of IntelliJ which everybody was accustomed to). Eclipse alone was a nightmare to use (slow, imports not founds, etc).
On the OSGi side:
There is no package manager. One team tried to set up maven but they failed. We just loaded jars.
The manifest files were a mess. Eclipse launch configurations were a mess (had to be re-imported after any change).
A small project which only required a backend was needlessly split into 5 parts. Over-engineering at its finest.
About reliability, I can only say that it is very reliable. It has to be, since it was developed to continue running, even if one of the loaded plugins crashes. Imagine running plugins for the ABS, entertainment and navigation system and the navigation system crashes. With OSGi the navigation system can be restarted without impacting other more crucial components.
I hear sometimes people saying, Java modules are a replacement for OSGi. This sounds to me a lot like saying that Blockchain can be used as distributed storage system.
This is exactly the Erlang 'let it crash' philosophy. Supervisor 'processes' (message-passing green threads) run concurrently and monitor and restart each other as necessary.
The only difference is that this is not at the plugin level but at the process level, a core lightweight concurrency primitive provided by the Erlang runtime.
The article claims "OSGi provides the type safety between modules that Java provides between classes" but I didn't see any of that.
Just a ton of services and modules that send message around that let to so much decoupling that you didn't have any Java language support anymore.
It looked like trying to do OO in C. You can do that but then you are completely on your own and have to ensure everything by hand.
I am in need of a way to allow plugins/integration with other teams. If we use standard Java package sharing mechanism, sooner or later teams will run into dependency conflict hell. More often, microservices (IPC) is suggested, too. But, the nature of our application is sensitive to latency and require high throughput. That throws IPC out of the picture.
Then, I remember the servlet API and how the servlet spec dictates classloading isolation at the container level. I rolled my own classloader to isolate the plugins/integrations but it is not as nice as OSGi implementation.
At this point, I am very inclined into using OSGi just for the sole classloading purpose.
One question that bother me is: since we are not that hardcore OSGi users, would it make sense for us to just bundle every plugins' into a fat jar and use bundle-classpath to resolve the plugin's owned dependencies? I know that by doing so, we are not strictly adhere to OSGi classes' sharing but it would lower the friction for independent teams to integrate with us.
peer class loading (as opposed to hierarchical)
dependency resolution
dependency specification and module (bundle) packaging
This makes OSGi an all or nothing solution: to use OSGi class loading you are forced to package your code in a specific way - which in turn makes it difficult to reuse existing libraries.
Lack of peer class loading has been a long standing pain point in Java - and in my opinion one of the main obstacles for really interesting use cases - especially related to mobile code ( see Jini ).
Now, OSGi may have a poor image in the current Microservices/cloud vendor driven bubble. But let’s step a bit back and ask: 1. isn’t constructing software from building-blocks useful? What’s up with reuse, synergy, not throw away software?
2. Wouldn’t services be useful that don’t just die but reconfigure (adapt) when upstream dependencies change/go away?
3. Is time to market really the best incentive these days? What’s up with making sure software is constructed with security and privacy in mind? What about assuming your startup isn’t sold (sell and forget) but you need to evolve it?
So, incidentally those qualities are part of the OSGi values made up about 20 years ago. If not OSGi (a messenger of values), wouldn’t the values make more sense now more than ever?
What about „green“ software development?
/ Toni
Java RMI, CORBA etc. have failed. Is OSGi somehow an RPC mechanism?
why?
to solve the hypothetical issue of needing two services that depends on different version of the same libraries within the same jvm
everything else it does you could do better with dependency injection and locator/proxy patterns