i think i'm missing the point of your rant. are you just ranting about how OSGi
is used? or is it about some particular build of bundles for OSGi? or is there
some problem with OSGi itself?
ben
________________________________
From: Craig Phillips <[email protected]>
To: OSGi Developer Mail List <[email protected]>
Sent: Wednesday, December 17, 2008 7:23:11 AM
Subject: [osgi-dev] separating api from impl rant
Hi,
Thinking about "osgi in action" et al... One thing I keep talking up, and have
yet to find the time to actually put a rudimentary demonstration together, is
along the following... [please pardon any mis-spellings and typos and
occasional jumbled sentence fragment(s) if they happen, not to mention any
relative ignorance on my part as I've been slightly away from OSGi in practice
for a couple months]
Admittedly, computers have to be rebooted, but in theory, IMO, an OSGi
container (and, distributed portions thereof) should be able to run 24x7 for a
complete application (loosely defined) life cycle; I see declarative services
(and, the variants thereof, from iPOJO and Spring-DM et al) as a key mechanism
for accomplishing and managing forward/backward compatibility and things like
OBR (and, shrug, this P2 thing) for deployment management, especially under
"low stress";
Furthermore, this rant also has implications to build, as build is not fun and
is not made any more pleasant by the massive infrastructures being put together
by these monstrous tools (for which I am too keenly subjected to on a daily
basis and the state of today's build-state simply sucks big time);
In my quest, shall we say, I mostly want to take advantage of the versioning
that OSGi provides (although I want the versioning at the service level, not
just the package level -- pardon my ignorance if I'm off a bit) and to push for
serious separation of API from IMPL;
It seems as if at least a generation of programmers out there simply missed the
boat and all the Grady Booch / "main sequence band" lessons regarding component
circular dependencies... Hey, I had to get BSF/j-ruby/groovy working within the
context of an equinox container and had to resort to "buddy policy: dependent",
not to mention a more than interesting experience of writing my own custom
class loader in order to make all that happen;
I contend that there should be a non-binding rule that APIs be non-activated
bundles in their own right, fully versioned (at the package level, since
"service" doesn't quite apply to a static interface, loosely speaking) [noting
that an API could be a non-abstract class, BTW];
So, APIs and IMPLs are NOT bundled together.. yeah, I can just hear the
"snorts" and "screams" and "chairs falling over" in the distance [nod to Ozzy
LOL]; First of all, build should ONLY use API.jar's; If I modify an IMPL.jar,
the hudson's of the world should not be kicking off a massive job, except maybe
for the sake of an integration test to run; Second, an IMPL can be deployed
without serious breakage to the world of existing OSGi based apps running on
the planet;
What I want to demonstrate, at run time (because I've ranted enough on how much
I hate what the state of build is today), is along the lines:
* A non-activated and versioned api.jar, let's say is version 1.0.0
* An impl.jar, as wired to api.jar in such a manner that it is clear that
impl.jar, at whatever version, implements api.jar at version 1.0.0;
* A client.jar which is wired to api.jar for version range 1.0 to 2.0, where
2.0 is excluded (meaning, anything less than 2.0);
So, life cycle continues... we find bugs and minor enhancements to impl.jar,
but they don't break / mod the api... Hence, we put out new deployments of
impl.jar, as still implementing api.jar at version 1.0.0, of varying minor
version increments; As we put out the new impl.jar increments, declarative
services is "unbind'ing" and "re-bind'ing" the service to client.jar; So far,
so good...
Now, we add items to api.jar.... we have no broken the backwards compatibility
to api.jar, so no need to bump the major version number. We just bump the minor
version portion; As such, we create a new version of impl.jar that supports
the mods to the api; And, as above, we can deploy this new and still backward
compatible set of api and impl jars with the unbind and re-bind to the
client.jar (noting that we have to STOP the old versions of the bundles and
should uninstall at a time in which we know there are no clients out there that
are wired specifically (meaning, not "ranged") to older/legacy bundles;
Speaking of said issue...
If client.jar had been wired specifically to api.jar at version 1.0.0 (assuming
this is even possible at the service level -- if the api is small, the package
level versioning will get the job done, but that's not exactly what I want /
desire), then we would not be able to STOP/uninstall the older/legacy
api.jar/impl.jar set; So, I'm assuming that client.jar can wire to the mod'd
API/IMPL application bundle set, even though it was "built" using api.jar at
version 1.0.0 [this is all run time stuff I'm referring to above -- hence,
client.jar has not be rebuilt]; And, of course, I assume the mod'd api as
implemented by the 1.0.1 version (or there abouts) of impl.jar, provides a
functional backward compatibility capability;
As for breaking backward compatibility, like in the case of a delete or rename
or maybe a really massive mod to the api, we bumped the major number of the
api.jar to 2.0.0; We can deploy the new 2.0.0 api.jar and 2.0.0 impl.jar into
the existing container and nothing in the older/legacy breaks -- it continues
to function using the older/legacy bundles, for which we did not
STOP/uninstall; Once a new client is deployed that uses api.jar at level
2.0.0, we can then go and STOP/uninstall the older/legacy client bundle;
Using the above, for which I have yet to demonstrate and have no certain
confidence level if this is achievable, at least using OSGi 4.1 (and, nothing
in the OSGi 4.2 spec that I see thus far leads me to alter my suspicions plus
or minus), but theoretically a container would otherwise be able to run 24x7
for the entire life cycle of an application (as implemented using OSGi et al as
"services");
And, back to build -- we don't need this monstrosity infrastructure if we were
to force proper programming practices in which API is fully divorced from IMPL;
Let's face it, impl's change a lot! But API's should be fairly stable; Hence,
hudson's shouldn't be busy running jobs constantly as they are today; Simply
put, if you mod an impl, hudson/CIs should only build the impl bundle and maybe
run an integration test and go back to sleep; In this day and age, it seems
that parent.pom changes on a daily basis, shrug; Where's the convention? Like
standards, just wait a day and a new one appears;
And when you started to add distributed services and Newtons and composites and
the like, it just gets more and more important that we have serious/significant
separation of API from IMPL; I tell everyone who will listen (and considering
this lost generation that doesn't know how to spell "main sequence band", there
aren't many out there who do "listen" -- just override this one method and type
mvn -- "pool's open!") -- get used to lots of little jar files! I think things
like Newton have ideas on how to manage "lots of little jar files", but I
haven't looked at that effort in a number of months...
For what it's worth... Well, I feel better LOL ... for now... Cheers, Craig
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev