2008/5/22 Saminda Abeyruwan <[EMAIL PROTECTED]>: > Hi Stuart, > > When users need to get code from legacy jars and load from TCCL, wouldn't > it be useful to give them the option of setting the OSGi aware classloader > to TCCL. May be a Felix specific manifest header will be suffix. >
would a default TCCL that supports legacy code be useful - of course! but my point was that the OSGi spec does _not_ mandate setting the TCCL to a specific classloader approach, so if you want to make sure your code works on all frameworks you need to be aware of this fact (otherwise your code would not be compatible with other frameworks) in fact the ContextFinder that Equinox sets as the default TCCL is not the same as the bundle classloader - it is in fact a very complex piece of code that attempts to find the correct classloader based on the call stack, and is specifically designed for legacy code. actually, you might be able use the ContextFinder in other frameworks but I have not tested this myself - setting the TCCL to the bundle loader is enough for most legacy libraries, but not all of them. When we design and implement OSGi aware code, we are always focus on writing > code to tally with OSGi semantics, such as using service registry, > class/resources load from bundle etc. But when we depend on 3rd part > dependencies, where the programmer has no control over or licence wouldn't > allow to change the code, if those jars try to load classes from TCCL , in > Felix OSGi implementation, this scenario will fail. IMHO loading classes > from TCCL is a very heavily used use case. > it would also fail on most other frameworks - in this case part of the work in OSGi-fying the legacy jar is setting the correct TCCL around the library call - using a "try...finally" approach to nest the call and restore the previous TCCL on return/exception (the nesting approach is important, as the caller of your code might want the TCCL set to a classloader that's not the bundle loader...) On the contrary, if TCCL reference to the root classpath, IMHO the > classloader isolation and version also fail. If we think parallel to host > Vs embed scenario of Felix, if the classpath where the system start > contains unwanted jars or if someone accidently set CLASSPATH global > variable, theses classes and resources will be visible from TCCL. Thus, the > whole purpose of classloader isolation will be lost. > Felix doesn't set the TCCL, so it just inherits the Java default. > IMHO if the TCCL and this.getClassloader() would be set sync, I believe in > programming perspective, it will really helpful for programmers to > visualize > the classloading and classloder delegation mechanism more clearly. > yes and no - it would help in some situations, but not others, such as when the TCCL is changed by other code - to make your library really robust you should explicitly set the TCCL to whatever you need (ie. bundle loader) before making the call and reset it afterwards. I'll wait for others to put forward their views - but I'm cautious about this sort of change because it can occasionally make life worse for developers, by hiding away reality - which then comes crashing back when their customer wants to deploy the app to another framework that doesn't set the TCCL... but I agree it is useful - but perhaps more as a utility method in your application, rather than a core piece of the framework. > Thank you! > > Saminda > > On Thu, May 22, 2008 at 3:43 PM, Stuart McCulloch < > [EMAIL PROTECTED]> wrote: > > > 2008/5/22 Saminda Abeyruwan <[EMAIL PROTECTED]>: > > > > > Did some debuging further. Class not found exception occurs when the > > > required class is loaded from TCCL. > > > "Thread.currentThread().getContextClassLoader()" > > > When I checked the TCCL, it's not OSGi aware (it's not create from > > Felix). > > > TCCL contains the classloader coming from the boot classpath. Is this > the > > > accepted behaviour ? > > > > > > > from what I remember the OSGi spec doesn't mandate > > setting TCCL to the bundle classloader, although some > > frameworks like Equinox do set it to help legacy code > > (they set it to a ContextFinder, which != bundle loader) > > > > if you want access to the bundle classloader, select a > > class, or instance, that was loaded by that bundle (like > > the activator) and use class.getClassLoader() > > > > or alternatively use loadClass() method from the bundle > > object, which you get from the getBundle() method on > > the bundle context, and this will use the right loader. > > > > btw, you can also use services to support loading of > > classes or instances from other bundles (just register > > your own service to do this that provides some sort > > of builder API) > > > > HTH > > > > Saminda > > > > > > On Thu, May 22, 2008 at 2:48 PM, Marcel Offermans < > > > [EMAIL PROTECTED]> wrote: > > > > > > > Can you strip the example up to the point where we can have a look at > > it? > > > > It could be that the class that refuses to load needs something that > is > > > not > > > > available. > > > > > > > > Greetings, Marcel > > > > > > > > > > > > On May 22, 2008, at 11:14 , Saminda Abeyruwan wrote: > > > > > > > > "." is present > > > >> > > > >> Saminda > > > >> > > > >> On Thu, May 22, 2008 at 2:33 PM, Marcel Offermans < > > > >> [EMAIL PROTECTED]> wrote: > > > >> > > > >> On May 22, 2008, at 10:09 , Saminda Abeyruwan wrote: > > > >>> > > > >>> Bundle A exports some package "a.b". In addition to this, this > bundle > > > >>> > > > >>>> embed > > > >>>> a foo.jar and manifest has Bundle-Classpath: foo.jar > > > >>>> > > > >>>> Bundle B imports package "a.b". Say the activator of bundle B > calls > > a > > > >>>> class > > > >>>> of this package. When this happen, I'm seen a class not found > > > exception > > > >>>> from > > > >>>> a.b class, which is available in foo.jar. When bundle B's class > > loader > > > >>>> delegates to bundle A's class loader, this shouldn't be a problem. > > Am > > > I > > > >>>> doing something wrong ? > > > >>>> > > > >>>> > > > >>> If my memory serves me well, you need to explicitly include "." in > > the > > > >>> bundle classpath, so: > > > >>> > > > >>> Bundle-Classpath: ., foo.jar > > > >>> > > > >>> Greetings, Marcel > > > >>> > > > >>> > > > >>> > > > >> > > > >> -- > > > >> Saminda Abeyruwan > > > >> > > > >> Senior Software Engineer > > > >> WSO2 Inc. - www.wso2.org > > > >> > > > > > > > > > > > > > > > > > -- > > > Saminda Abeyruwan > > > > > > Senior Software Engineer > > > WSO2 Inc. - www.wso2.org > > > > > > > > > > > -- > > Cheers, Stuart > > > > > > -- > Saminda Abeyruwan > > Senior Software Engineer > WSO2 Inc. - www.wso2.org > -- Cheers, Stuart
