I think I'm happy with it now, though it has took some time getting here. I suspect Peter Kriens could pick holes in this (please), but I feel this is a good representation of how the bundles in Gaikokugo, my language learning application, look:
This morning I decided to email my friend and mentor John Skelton, co-author of Schaum's Outlines: UML to ask for some advice. As I was explaining the situation to him I essentially made the breakthrough that I realised it simply isn't important to show the bundle that the interface (the service) is declared in and everything else just fell in to place. Looking back I think Peter had been trying to drill this in to my thick head. =)
For instance, in a more complicated example I've been using at work, I have the interface out on it's own. The bundle that contains the interface uses the interface, even though it also declares it but the interface is not shown within a bundle, it is just shown out there being used by various bundles. By drilling down in to the UML model you can see which bundle the interface belongs to and so I have shown this in a seperate package (class) diagram. These diagrams are going to become part of the softare architecture document I'm writing (which is a new one for me as I usually hate writing them, but am enjoying it this time - perhaps I'm getting old?).
So in the above diagram, I have used an absolutely bog standard UML2 implementation diagram (aka component diagram). I think it's pretty clear that the "db" bundle exposes the interface, that the "db.db4o" bundle implements the interface and that the "rcp" and "db4o.test" bundles use the interface. There's no mention of a dependancy on the bundle that exposes the interface, just the interface itself, which is the best approach for keeping the system as loosely coupled as possible. In the above example the interface is shown inside the bundle that contains the interface is only shown because it doesn't do anything with the interface itself.
The one thing that is missing in the diagram above is the service listener that Peter mentions in his article ( as part of the register, get, listen operations that can be done on a service) but I am happy this can be represented with a simple dependancy connector that states the relationship is one of listener.
In conclusion, this is perhaps not as elegant as Peter's notation, but I'm happy that I can get the message across using UML. I can imagine that the diagrams could get complicated, but at the same time that kind of forces the architect to break things down in to more managable chunks. That would mean it is hard to get a view of the big picture, so it is a matter of swings and round-abouts.
Oh, and I did find a free tool for doing drawings, it was in Open Office! It's the first time I've had office software on my personal hardware for ages as I have been using Google Docs for some time now. Hopefully Google will come up with a nice online collaborative drawing tool next - hint hint! ;-)
Now, my next problem is exposing my OSGi services as WebServices, but I'll leave that one for another post.