On Thu, Jan 6, 2011 at 2:58 PM, Alex Karasulu <[email protected]> wrote: >> In the end, dependency upon further transitive dependencies are making us >>> expose almost all implementation classes in shared, and most can easily be >>> decoupled and hidden. It's effectively making everything in shared come >>> together in one big heap exposing way more than we want to. >>> >> It's quite impossible in Java to 'hide' all the classes that a user should >> not manipulate. Unless you use package protected classes, and it quickly has >> a limit, I would rather think in term of 'exposed' (ie documented) API. > > > OSGi bundles really helps in this respect. It fills in where Java left off. > > OSGi makes it so the (bundle) packaging coincides with module boundaries. In > Java this is loose and there's leakage all over, as you say, it's very hard > to hide all implementation classes. > > >> That this documented API is gathered in one separate module for convenience >> is another aspect, but the user will still have to depend on all the other >> modules. >> >> > Certainly, you're right, dependencies will still exist. A codec will be > depended upon for it's functionality even if we do hide the implementation > details under the hood. > > The value add here is not from avoiding a dependency. It's from not exposing > more than we have to and being able to hide the implementation. This way we > can change the implementation at will across point releases without having > to bump up to a major revision. > > >> So all in all, should we define a module (a maven module) containing the >> public API and the associated implementation ? Probably (But this is not an >> absolute necessity). I guess this is what you have in mind, so let's see >> what's the proposal is... >> >> > We have multiple options for chopping this up. With bundles we have a nice > tool to carve out physical not just logical boundaries to our API's and only > expose those packages we need to show API users.
> > >> >>> LDAP Client API >>> ------------------------ >>> >>> Everyone agrees that this API is very important to get right with a 1.0. >>> Right now this API pulls in several public interfaces directly from >>> shared. >>> Those interfaces also pull in some implementation classes. The logical API >>> extends into shared this way. Effectively the majority of shared is >>> exposed >>> by the client API. The client API does not end at it's jar boundary. >>> >>> All this exposure increases the chances of API change when all >>> implementation details are wide open and part of the client API. And this >>> is what I'm trying to limit. There are ways we can decouple these >>> dependencies very nicely with a mixed bag of refactoring techniques while >>> breaking up shared-ldap into lesser more coherent modules. The idea is to >>> expose the bare minimum of only what we need to expose. Yes the shared >>> code >>> has become very stable over time but the most stability is in the >>> interfaces >>> and if we only expose these instead of implementation classes then we'll >>> have an awesome API that may remain 1.X for a while and not require >>> deprecations as new functionality is introduced. >>> >> >> How will you limit the visibility of the modules you don't want the user to >> be exposed to ? >> >> > A combination of refactoring techniques will be used to be able to better > use standard Java protection mechanisms to hide implementation details > combined with using OSGi bundles instead of Jars to only export those > packages that we do want users to see. Alex, I agree with you that separating interfaces and implemenation details is a good thing. Also creating OSGi bundles with a minimal set exported packages is a good thing. But it only helps if the bundles are used in an OSGI environment. I think we'll continue to deploy those OSGi bundles (which are just Jars with a good META-INF/MANIFEST.MF) to maven central. And each user using those Jars will see and can use all classes, when not using an OSGI environment. So I think we need additional techniques for non-OSGi users to let them know which packages to use, for example: - Use a naming convention for internal packages, the name "internal" is used in Eclipse and Apache Felix, not sure if is specified in OSGi. - Create separate Jars for API and implementation (e.g. xyz-api.jar and xyz-impl.jar) Kind Regards, Stefan
