The benefits of sharing—and how to achieve them in your bundles
You're probably wondering why we make such a big deal about sharing code; sure it
sounds great in theory, but is it ever practical? Even if it's practical, is it worth the extra
effort and loss of control?
Interestingly, both of these questions were initially raised about object-oriented
programming ( OOP ), which was also introduced in an effort to increase reuse. Like
OOP , the benefits of the new model in OSG i seem too good to be true, offering a theo-
retical reward that's almost impossible to achieve in practice. Thankfully, OOP has
proved to be a much better model for writing code that needed to work in a large sys-
tem, but only if you made use of the tools available. The same is true of OSG i, and
there are some simple rules you can use to determine whether what you're writing will
be a nice, reusable bundle, or if it will be a slightly mangled JAR .
Clearly there's a significant cost associated with writing a piece of code. Even vol-
unteered development time isn't free; by spending time writing one piece of code,
you're always taking time away from other pieces of code that need to be written.
What isn't typically factored in is the cost of using code that has already been written.
Sure, you don't have to pay to write it again, but repackaging code when you need to
update a dependency for a bug fix is time consuming, uses computing resource, and
may in the long term lead to the sort of JAR hell we saw in chapter 1. More problems
arrive if you have to switch to a different implementation of a library that's ostensibly
doing the same thing. It usually takes a lot of time and testing to find and fix all the
places that were hooked into the old implementation.
The cost of using and maintaining code depends to a great extent on how well mod-
ularized the code is. It sometimes helps if you think of a bundle as a puzzle piece. If your
bundle has a lumpy, bumpy shape, then it's almost certainly coupled to its dependen-
cies (the other puzzle pieces around it) in a complex and brittle way. Although this
shape may help in identifying the pieces of a puzzle, it doesn't help when reusing bun-
dles. The chances are that if the bundle or its dependencies change in any way, the
result will change the shape of the pieces so that they don't fit together anymore, caus-
ing a failure. If your bundle is well modularized, it will have a simple shape, meaning
that it's much easier to find pieces that fit with it (see figure 5.1). Clearly this doesn't
help you finish a puzzle, but it does make it much easier to reuse code!
Another cost that's almost always overlooked by developers, but significantly affects
infrastructure, is how things are shared at runtime. Although you may have saved lots
of money at development time by using a library in the twenty applications running
on your system, if that library is loaded twenty times you still need to pay the footprint
cost at runtime. In many systems this is a real problem, running to hundreds of mega-
bytes, that adds a significant cost over the lifetime of the application. The problem is
particularly obvious in cloud environments, where there's a direct price tag attached
to application memory usage.
If you get your sharing right, then you can bypass both the cost of rewriting and the
cost of repackaging your code. If you get your sharing really right, then you can reduce
or even eliminate the cost of switching implementations, and the cost of loading the