Hi, I'll wade in... Been using OSGi (felix) for several years...
So, you have package versions, but you don't have service versions. Also, I embed OSGi, I don't use it standalone. OSGi is the Java we should have had back in 1995 and part of the language from conception. Frankly, I consider OSGi "java++"; Typically, I embed OSGi in other "greater" operators / components. Typically, those higher level APIs are message based, but not always (e.g., embed OSGi inside a web-app). The reason I bring this up is that you typically don't have such nice version range features and you have to come up with similar features on your own. One key thing about version conventions as applicable to your post I MUST get out of the way up front: A major number bump should signify breakage in terms of [forward] compatibility. A breakage is something like a delete or a rename, but may also be a semantic kind of breakage where things don't work and old things should no longer wire to them. The same kind of principle can be applied to things that don't have version [range] features built in. In this case, as you may be guessing, you simple put a major version in the name of the construct. For example, take an hbase table - since these are somewhat schema-less. I append a major version, such as "<MY_TABLE>_V1"; This way, if the schema-less table changes form to the point that there is breakage, you can create a new "<MY_TABLE>_V2"; Anyway, although you can't version an OSGi service (OK, I've been out of the OSGi specification loop for a while), you can do the same kind of protection scheme. As for services, I have a convention that has worked very well for several years: you create an API bundle and you separate the implementation into separate bundle(s) - noting that APIs are generally stable (if your APIs are not stable, you have spent little time on your requirements analysis and your architecture process is abysmal). I must also point out another feature I invented (OK, I'm sure I'm not the ONLY one out there to have invented this, but I did invent it for my project nevertheless): "repository watcher"; Bundles are created with the version number in the name. They are placed into an execution repository. Many so called engineers and system support people rarely get the concept of an execution repository. Oh sure, they get the notion of a build repository - and then the mavenize the BLANK out of it - but they have no clue when it comes to an execution repository. First things first, there should ONLY be APIs in a build repository. An execution repository is not structured like a build repository. An execution repository is structured into "execution components" and common use partitions. The "repository watcher" is given a list of execution repositories to monitor. The bundles are installed into an embedding container (e.g., an instance of Felix inside some greater component context like a streaming platform or a web-app and so forth). But the bigger aspect is that the repository watcher maintains the list of what's in the container versus activity occurring in the execution repository. The key convention is that the latest major number bundle is installed and all lesser versions are removed as activity occurs in the execution repository(ies). So, old and new major version can run together in the same container and all wiring is appeasing. As you remove items from the execution repository(ies), those items are removed from the container. In a development environment, things are volatile, but it all "holds water"; This allows you do maintain your deployments, distributed as they may be, by simply maintaining your execution repository. The watchers take care of the rest. That's probably enough to digest in one sitting. As always, I continue to sneer at the specification process for not incorporating the notion of "source bundle" (a builder inside the system bundle) and recognizing that "the framework is the convention" and not some ridiculous arcane build tool that starts with the letter "M". But I digress. Cheers ________________________________ From: [email protected] [[email protected]] on behalf of Lindsay Smith [[email protected]] Sent: Sunday, July 31, 2011 6:46 PM To: [email protected] Subject: [osgi-dev] Maintaining package versions Hi all, I’ve got some questions about development lifecycle of OSGI components, and specifically maintaining and using package versioning correctly. All the rationale behind having package versioning is sound in my opinion, OSGI has the right abstraction. In my experience the hard part really is how this is realised through day to day development practices. I architected the transition of our middleware product from a ‘standard’ Java application to an OSGI-architected one. The main driver for us was the class isolation that OSGI can provide – and this was most important for us not for our own components, but for classes that are defined by end users of the platform. The transition was on the whole very positive, our architecture is much more solid I think, and the build process went from a monolithic build to many individual components. Since time was tight we never introduced packaging versioning, and never have. We still rely on ‘naïve’ jar versioning, and manually manage package level issues as they arise. I suspect that many OSGI systems are the same. I’m attracted to having proper package versioning on our components, but frankly I can’t work out how to integrate it into our development process. Put simply, if you have to maintain the package versioning manually, it’s never going to work. Unless tools can automate the package versions (at least at the export side), I don’t think the cost will ever outweigh the benefit. I feel that this points to the heart of the ‘complexity’ argument that detractors of OSGI make – while the model is sound, unless the model is inherent at every level of development and deployment then it cannot be adopted without introducing the need for ‘expert’ (in that it’s not common) knowledge about OSGI into the development cycle. Anyway, I have some questions about package versioning which I hope can enlighten me and help me towards some kind of solution path. The Bnd tool is the canonical tool for managing package versions in the manifest. I’m interested to know – how does it work out imported package versions? Does it directly read the manifest of the bundles referenced by your bundle? What tools are there for maintaining your package versions? Is there a tool that I can use to detect API changes between two versions of a bundle? For such a tool to work, you need something to compare it to – so what’s the standard for the ‘last thing to compare to’? The last released version? The last built version? This part is crucial – it seems to me you need a build system that can go and find the last released version all by itself (maven style, although my impression is that that’s a dirty word around here) and fail if your package versions have not been set correctly. Using the last released version makes sense to me since that’s all that really matters – steps of interim changes are irrelevant. I am aware of the bndtools project – and this shows some real promise as an alternate, lightweight set of tools for managing bundle development. I haven’t found it useful yet, it’s still under development and I’m not sure that our workflow fits into its model, but I check on it all the time for progress. More docs would be great. Thanks in advance Lindsay
_______________________________________________ OSGi Developer Mail List [email protected] https://mail.osgi.org/mailman/listinfo/osgi-dev
