Hi Thomas, For use case 1, my main concern is as described before : A wants to use objects of class B, that's all. Whether B is implemented "monolitically", copy/pasting all implementation code in a single class file, or by composition or through extending some base class, should preferably be a localized implementation decision of the B developer. The A developer should need to be confronted with this, I think.
It's similar to when you write "plain" Java code. When you need class B, you just add one import statement in your A src file, to import B. You don't need to add import statements for all base classes in B's class hierarchy... Stated differently : what does an export-package do for a bundle? Does it export just the "fragment" of the classes in the package, corresponding to the specific interface/source code in there? Or does it export a full "view" on the classes? (this is of course not an easy problem, and is indeed related to transitive dependency mgmt at compile/run time as mentioned by someone before etc...) Or still otherwise said : if I really am not using any C-related types in my A, why would I need to depend on it? If I am using such types, it would indeed be logical that I need to formalize that in my MANIFEST, else it seems to be a total encapsulation-killer? And that last line-of-thought is also what's in my mind for use case 2... For your questions : - A may indeed not be interested in the C-methods. But to stretch the discussion even a bit further ;-), even if it would, and it accesses those methods through B, why exposing a dependency to C at all? (again, in plain Java src code I wouldn't even be aware of C, I would just be using/referring objects of class B) cheers erwin isencia. On Wed, Jan 30, 2013 at 9:52 AM, Gillet Thomas (2) < [email protected]> wrote: > Hello Erwin, hello all,**** > > ** ** > > I’m also struggling with some dependency problems when using this kind of > “one base bundle & a lot of implementer bundles” pattern (that is, > polymorphism on the OSGi level).**** > > But before entering the discussion, I would like to be sure I really > understood your problem.**** > > ** ** > > You described 2 use-cases:**** > > **· **A ---use---> B ---extends---> C**** > > **· **A ---extends---> B ---use---> C**** > > ** ** > > In the first case, from what I understood, you don’t want A to depend on > C, because A doesn’t use any of the methods declared in C.**** > > But then I wonder, if A is not interested in those methods, why are they > exposed to A at all?**** > > Is it:**** > > **· **Only because B extends C (meaning B should actually inherits > privately from C, if such a thing were possible)?**** > > **· **Because other clients of B do use those methods (A being the > one particular case without need for C methods)?**** > > **· **Because I totally missed your point?**** > > ** ** > > Same questions goes for the second case, yet in slightly different terms. > But same general idea.**** > > ** ** > > As you can see I’m only interested in your concept and design pattern.**** > > That’s because I’m not a PDE user, nor very interested the internals of > the Java compiler.**** > > ** ** > > --**** > > Thomas GILLET**** > > Volvo Trucks – Advanced Technology & Research**** > > ** ** > ------------------------------ > > *From:* [email protected] [mailto: > [email protected]] *On Behalf Of *Neil Bartlett > *Sent:* mardi 29 janvier 2013 17:58 > *To:* OSGi Developer Mail List > *Subject:* Re: [osgi-dev] What to do with "inherited" dependencies**** > > ** ** > > ** ** > > ** ** > > On Tue, Jan 29, 2013 at 4:28 PM, erwin dl <[email protected]> wrote:**** > > Thanks all for your feedback. > > But in this case, I don't want to revert to hacks to bypass dependency > declaration impact. > And going for artificial composition would be a hack, how strange it may > seem. > > E.g. the adapter implementations ARE adapters. > They don't HAVE adapters (i.e. the classical IS-A vs HAS-A thing does not > help me here). > > Composition is ok when you have things to compose. > Also, using interfaces as refered types is the default approach in our > stuff. > > But at some point the varying implementations must be just .... > implemented... > And then it's nice to be able to define common stuff in a base-class, i.o. > needing to copy it around every time or artificially forcing in a couple of > design patterns. > Even when building modular solutions... > > I need to reflect some more on this to find the fundamental issue, > but I have the impression that there is a kind of mismatch between > "encapsulation of dependencies" versus "needs related to (ease of?) > compilation". > > Especially in the first case I described, it would be nice if the choice > to implement a given ClassB via inheritance or via copy/paste, could be > encapsulated in the bundle B's implementation. > Without needing to expose this as a forced dependency on "client" > bundles... > > Neil, as you explain indeed, for the second situation I described before, > replicating dependencies could be considered a bit more natural than in the > first situation. > Although even in the second case I would assume that as long as class A > does not contain any reference to any C-types, there is no need to > replicate this dependency in bundle A. > You also don't need to add any C-related import statements in the Java > source code of A, after all?**** > > ** ** > > Yes, as I said, the direct runtime dependency *may* not be needed. If you > used bnd/Bndtools then the Import-Package would be added if-and-only-if you > directly used C from within A. However you would still need C on the > compile-time classpath for project A, because the Java compiler needs it. > You cannot get around that fact if you structure your code this way.**** > > **** > > > (but I must confess : I don't know the internals of class loading or > compiling; I'm just looking at it from a design and development perspective) > > cheers and thanks again for your time and thoughts! > > erwin**** > > > > **** > > On Tue, Jan 29, 2013 at 2:30 PM, Toni Menzel <[email protected]> > wrote:**** > > Thanks Neil, actually with "composition" i included the use of OSGi > Services. Its the old story that is true not just in OSGi: avoid > inheritance if you seek true modularity.**** > > > **** > > *Toni Menzel | Founder **Rebaze GmbH***** > > [email protected] | +49 171 65 202 84 <%2B49%20171%2065%20202%2084>** > ** > > http:// <https://mail.google.com/mail/u/0/goog_1770677242>www.rebaze.com > | twitter @rebazeio <https://twitter.com/rebazeio> | LinkedIn > Profile<http://www.linkedin.com/company/2553599> > **** > > ** ** > > *Rebaze Pilot: *The free one day onsite consulting opportunity. We will > capture your potential.**** > > *Rebaze Pass: *A unique subscription service for key technologies in your > project.**** > > *Rebaze Onsite: *Our way to improving your development team on site.**** > > ** ** > > On Tue, Jan 29, 2013 at 2:21 PM, Neil Bartlett <[email protected]> > wrote:**** > > This seems an entirely reasonable requirement. It doesn't come from PDE as > such but from the Java compiler. A directly inherits from B. The public > interface of B uses types from C (as you said, C is either a method > argument or return type). Therefore the Java compiler needs visibility of > both B and C when it compiles A.**** > > A direct runtime dependency from A to C *may* not be necessary if A > doesn't use the C types at all. Unfortunately PDE does not allow for > separation of compile-time versus runtime dependencies, so you still have > to add the Import-Package in order to create the compile-time visibility.* > *** > > ** ** > > This could possibly be avoided if you make more use of Java Interfaces and > OSGi services. For example, make sure that all implementation bundles (i.e. > those containing executable code) depend only on the interfaces, and not on > each other.**** > > Neil**** > > ** ** > > On Tue, Jan 29, 2013 at 12:27 PM, erwin dl <[email protected]> wrote:**** > > Hi Toni, > > Thanks for your quick advice. > And indeed that's what I do :**** > > - I am using package imports, not bundle dependencies**** > - Composition is the default approach, but just doesn't cut it in all > situations**** > - In general I do try to follow all kinds of rules for "good modular > and OO design"**** > - But in some concrete design situations I am trying to match it to > minimal module/bundle dependencies, which is also a rule I have**** > - And the sketched situation bothers me in that respect**** > > As an extra, I also encounter following situation, as a slight variation > on the previously described one : **** > > - ClassA now inherits from ClassB (again in 2 separate bundles). In > fact there are many different subclass implementations of ClassB, all in > different implementation bundles.**** > - ClassB depends on a ClassC in a bundle C, in one of its method > signatures (i.e. ClassC is used as an argument or return type)**** > - I get an error in the PDE compilation : "The type ClassC cannot be > resolved. It is indirectly referenced from required .class files"**** > - As a consequence it seems I also need to add an explicit dependency > (done via import package) of all implementation bundles (like bundle A) to > the bundle C. > Whereas I would hope/expect that this dependency is already clearly > defined in bundle B...**** > > With some more concrete explanation :**** > > - We're building a modular processing engine, that can be extended > with specific "backend adapters" to perform data collection to/from other > systems**** > - Most complexity of the adapter is implemented once and reusable, in > an adapter base class e.g. "BaseBackendAdapter".**** > - The adapters are used by a common "BackendService" implementation > that has a reference to its adapter (i.e. composition). The reference is > typed to the "BaseBackendAdapter". > BackendService and BaseBackendAdapter are provided in a common "base" > bundle.**** > - Each concrete adapter bundle registers a BackendService instance, > with its dedicated concrete adapter, as an "OSGi" service etc. > Implementation code in the concrete adapter bundles depends really on > actual communication APIs etc.**** > - So I would prefer to have just 2 main dependencies : on the base > bundle and on the concrete communication API.**** > - Problem is now, that I need to replicate some dependencies of the > "base" bundle in each concrete adapter bundle, which I don't like...*** > * > > ** ** > > cheers**** > > erwin**** > > ** ** > > ** ** > > On Tue, Jan 29, 2013 at 1:01 PM, Toni Menzel <[email protected]> > wrote:**** > > Quick answer to parts of your question:**** > > - Prefer composition over inheritance. Just don't build on inheritance > and your developer life, not just the OSGi one, will be better ;)**** > - Avoid Bundle dependencies. If you encounter a situation where you > have the abstract class and the final one in same package you should carry > it around in one bundle. Otherwise just make the abstract one explicit by > giving it a separate package. (avoid split package)**** > > You learn this quickly by avoiding PDE.**** > > Toni**** > > ** ** > > > **** > > *Toni Menzel | Founder **Rebaze GmbH***** > > [email protected] | +49 171 65 202 84 <%2B49%20171%2065%20202%2084>** > ** > > http:// <https://mail.google.com/mail/u/0/goog_1770677242>www.rebaze.com > | twitter @rebazeio <https://twitter.com/rebazeio> | LinkedIn > Profile<http://www.linkedin.com/company/2553599> > **** > > ** ** > > *Rebaze Pilot: *The free one day onsite consulting opportunity. We will > capture your potential.**** > > *Rebaze Pass: *A unique subscription service for key technologies: OSGi, > Maven, Chef, Jenkins.**** > > *Rebaze Onsite: *Our way to improving your development team on site.**** > > ** ** > > On Tue, Jan 29, 2013 at 12:41 PM, erwin dl <[email protected]> wrote:**** > > I often encounter situations where a certain class ClassA in a bundle A > depends on a class ClassB in a bundle B, and where ClassB is a subclass of > ClassC in a bundle C. > > So it is logical that bundle B has a dependency on bundle C. > > But to get the things compiled and working, I am forced in such a > situation to also add an explicit dependency of bundle A on bundle C. > Even when not directly referring to the base-class in my ClassA... > > At least this is true in eclipse's PDE. > But in internal discussions here, it seems to be perceived as an > inevitable fact, independent of eclipse or equinox implementation choices... > > I would prefer that the implementation decision of ClassB, to inherit part > of its stuff from ClassC, i.o. implementing it directly itself, would be > hidden for ClassA and bundle A. > > I.e. it is not a situation where a kind of API is provided in bundle C, > and where bundle A would better use the API, and where bundle B provides > implementations as services etc. > It's a simple class-hierarchy set-up that exposes implementation decisions > and forces dependents to add a-priori "unnecessary" extra dependencies... > > If someone has advice or ideas on this, I would be very interested to > hear/learn from them! > > Many thanks, > erwin**** > > _______________________________________________ > OSGi Developer Mail List > [email protected] > https://mail.osgi.org/mailman/listinfo/osgi-dev**** > > ** ** > > > _______________________________________________ > OSGi Developer Mail List > [email protected] > https://mail.osgi.org/mailman/listinfo/osgi-dev**** > > ** ** > > > _______________________________________________ > OSGi Developer Mail List > [email protected] > https://mail.osgi.org/mailman/listinfo/osgi-dev**** > > ** ** > > > _______________________________________________ > OSGi Developer Mail List > [email protected] > https://mail.osgi.org/mailman/listinfo/osgi-dev**** > > ** ** > > > _______________________________________________ > OSGi Developer Mail List > [email protected] > https://mail.osgi.org/mailman/listinfo/osgi-dev**** > > ** ** > > > _______________________________________________ > OSGi Developer Mail List > [email protected] > https://mail.osgi.org/mailman/listinfo/osgi-dev**** > > ** ** > > _______________________________________________ > OSGi Developer Mail List > [email protected] > https://mail.osgi.org/mailman/listinfo/osgi-dev >
_______________________________________________ OSGi Developer Mail List [email protected] https://mail.osgi.org/mailman/listinfo/osgi-dev
