The only contract WRT to TCCL that I know of is the EE specification. Every other use case out there is going to be underspecified.
Ultimately it's a very fragile contract, and is misused more than not. The only silver-bullet solution is to make the classloader part of the API interaction, either indirectly via a type, or introducing a more formal session notion. To be honest, I have long thought infinispan API needs a hibernate session style contract. The advanced invocation context feature is clunky and uses thread locals (which has problems of its own). If you had a session you can better control user interaction for things like this without screwing up your API, and you can do it with minimal perf overhead (it's just a tiny blob non-concurrent thread state that would get passed to the cache per invocation). On 5/9/11 10:37 AM, Pete Muir wrote: > Ok, let me stew on that ;-) > > On 9 May 2011, at 16:35, David Bosschaert wrote: > >> If you have a Bundle object or BundleContext object you can figure out what >> classloader is associated with that. Also, if you have a class from a bundle >> you can find out what it's classloader is (obviously). >> >> However, you need to have one of those things to find this out. There is >> nothing magically available in the current context to tell you what the >> current Bundle is. >> It's generally really easy for the caller though to find out what the >> classloader is, though... If you have bundle X, you'd know a class from that >> bundle a.b.c.D (any class will do). Then you can simply call >> D.class.getClassLoader() and you've got the Bundle Classloader. >> >> Hope this helps, >> >> David >> >> On 09/05/2011 16:27, Pete Muir wrote: >>> The issue that David raises is that in an OSGi env that this wouldn't be >>> done by OSGi so would be up to the user or would require some extra >>> integration library. I'm not even sure if this is possible in OSGi? David, >>> is there anyway for a framework to "find out" the current bundle >>> classloader in OSGi rather than having to be told it (i.e. push rather than >>> pull)? >>> >>> The idea is that in AS that by doing (a) it would require the integration >>> to make sure the TCCL is set before Infinispan is called (this is the way >>> many things are integrated into GF for example). >>> >>> On 5 May 2011, at 20:05, Emmanuel Bernard wrote: >>> >>>> Quick question. >>>> In case of 2.a (ie setting the TCCL), this is a requirement for frameworks >>>> and libraries using Infinispan, right? Not / never for a user application >>>> using Infinispan (in this case it seems that the application class loader >>>> will do the right thing and is set as the TCCL by the AS environment)? >>>> >>>> Emmanuel >>>> >>>> On 5 mai 2011, at 10:55, Pete Muir wrote: >>>> >>>>> I talked about this with Emmanuel last night, and we were >>>>> >>>>> a) concerned about the pollution of the API that this implies >>>>> b) not sure why we need to do this >>>>> >>>>> So I also spoke to Jason to understand his initial motivation, and from >>>>> this chat I think it's clear that things have gone off course here. >>>>> >>>>> Jason raised two issues with modularity/classloading in Infinispan: >>>>> >>>>> 1) Using the TCCL as the classloader to load Infinispan classes is a bad >>>>> idea. Instead we should use >>>>> org.infinispan.foo.Bar.getClass().getClassLoader(). >>>>> >>>>> 2) When we need to load application classes we need a different approach >>>>> to that used today. Most of the time the TCCL is perfect for this. >>>>> However *sometimes* Infinispan may be invoked outside of the application, >>>>> when the TCCL may not be set in AS7. Jason and I discussed three options: >>>>> >>>>> a) require (through a platform integration documentation contract) that >>>>> the TCCL must always be set when Infinispan is invoked. >>>>> b) Have some sort of InvocationContext which knows what the correct >>>>> classloader to use is (aka Hibernate/Seam/Weld design where there is a >>>>> per-application construct based on a ThreadLocal). Given this hasn't been >>>>> designed into the core, it seems like a large retrofit >>>>> c) Make users specify the CL (directly or indirectly) via the API (as we >>>>> discussed). >>>>> >>>>> Personally I think that (a) is the best approach right now, and is not >>>>> that onerous a requirement. >>>>> >>>>> We might want to make the TCCL usage pluggable for OSGI envs. Cc'd David >>>>> to get his feedback. >>>>> >>>>> On 4 May 2011, at 10:46, Dan Berindei wrote: >>>>> >>>>>> On Wed, May 4, 2011 at 5:09 PM, Pete Muir<pm...@redhat.com> wrote: >>>>>>> On 4 May 2011, at 05:34, Dan Berindei wrote: >>>>>>> >>>>>>>> On Wed, May 4, 2011 at 10:14 AM, Galder Zamarreño<gal...@redhat.com> >>>>>>>> wrote: >>>>>>>>> On May 3, 2011, at 2:33 PM, Sanne Grinovero wrote: >>>>>>>>> >>>>>>>>>> 2011/5/3 "이희승 (Trustin Lee)"<trus...@gmail.com>: >>>>>>>>>>> On 05/03/2011 05:08 AM, Sanne Grinovero wrote: >>>>>>>>>>>> 2011/5/2 Manik Surtani<ma...@jboss.org>: >>>>>>>>>>>>> On 1 May 2011, at 13:38, Pete Muir wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>>>> As in, user API? That's a little intrusive... e.g., put(K, V, >>>>>>>>>>>>>>>> cl) ? >>>>>>>>>>>>>>> Not for put, since you have the class, just get, and I was >>>>>>>>>>>>>>> thinking >>>>>>>>>>>>>>> something more like: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Foo foo = getUsing(key, Foo.class) >>>>>>>>>>>>>> This would be a pretty useful addition to the API anyway to >>>>>>>>>>>>>> avoid user casts. >>>>>>>>>>>>> Maybe as an "advanced" API, so as not to pollute the basic API? >>>>>>>>>>>>> A bit like: >>>>>>>>>>>>> >>>>>>>>>>>>> Foo f = cache.getAdvancedCache().asClass(Foo.class).get(key); >>>>>>>>>>>> doesn't look much better than a cast, but is more cryptical :) >>>>>>>>>>>> >>>>>>>>>>>> getting back to the classloader issue, what about: >>>>>>>>>>>> >>>>>>>>>>>> Cache c = cacheManager.getCache( cacheName, classLoader ); >>>>>>>>>>>> >>>>>>>>>>>> or >>>>>>>>>>>> Cache c = cacheManager.getCache( cacheName >>>>>>>>>>>> ).usingClassLoader(classLoader ); >>>>>>>>>>>> >>>>>>>>>>>> BTW if that's an issue on the API, maybe you should propose it to >>>>>>>>>>>> JSR-107 as well ? >>>>>>>>>>> We have a configurable Marshaller, right? Then why don't we just >>>>>>>>>>> use >>>>>>>>>>> the class loader that the current Marshaller uses? >>>>>>>>>> +1 >>>>>>>>>> I like the clean approach, not sure how you configure the "current >>>>>>>>>> Marshaller" to use the correct CL ? >>>>>>>>>> Likely hard to do via configuration file :) >>>>>>>>> Well, the marshaller is a global component and so it's a cache >>>>>>>>> manager level. You can't make any assumptions about it's classloader, >>>>>>>>> particularly when lazy deserialization is configured and you want to >>>>>>>>> make sure that the data of the cache is deserialized with the correct >>>>>>>>> classloader when the user reads the data from the cache. This is >>>>>>>>> gonna become even more important when we for example move to having a >>>>>>>>> single cache for all 2LC entities or all EJB3 SFSBs where we'll >>>>>>>>> definitely need multiple classloaders to access a single cache. >>>>>>>>> >>>>>>>> The current unmarshaller uses the TCCL, which is a great idea for >>>>>>>> non-modular environments and will still work in AS7 for application >>>>>>>> classes (so it's still a good default). It probably won't work if >>>>>>>> Hibernate wants to store its own classes in the cache, because >>>>>>>> Hibernate's internal classes may not be reachable from the >>>>>>>> application's classloader. >>>>>>>> >>>>>>>> It gets even trickier if Hibernate wants to store a >>>>>>>> PrivateHibernateCollection class in the cache containing instances of >>>>>>>> application classes inside. Then I don't think there will be any >>>>>>>> single classloader that could reach both the Hibernate classes and the >>>>>>>> application classes so it can properly unmarshal both. Perhaps that's >>>>>>>> just something for the Hibernate folks to worry about? Or maybe we >>>>>>>> should allow the users to register more than one classloader with a >>>>>>>> cache? >>>>>>> You need to use a bridge classloader in this case. >>>>>> You're right of course, Hibernate must have received/guessed the >>>>>> application's classloader and so it is able to create a bridge >>>>>> classloader that "includes" both. >>>>>> >>>>>> And if the application classes include references to classes from >>>>>> another module(s), the application has to provide a bridge classloader >>>>>> to Hibernate anyway. >>>>>> >>>>>> _______________________________________________ >>>>>> infinispan-dev mailing list >>>>>> infinispan-dev@lists.jboss.org >>>>>> https://lists.jboss.org/mailman/listinfo/infinispan-dev >>>>> >>>>> _______________________________________________ >>>>> infinispan-dev mailing list >>>>> infinispan-dev@lists.jboss.org >>>>> https://lists.jboss.org/mailman/listinfo/infinispan-dev >>>> >>>> _______________________________________________ >>>> infinispan-dev mailing list >>>> infinispan-dev@lists.jboss.org >>>> https://lists.jboss.org/mailman/listinfo/infinispan-dev >>> >>> _______________________________________________ >>> infinispan-dev mailing list >>> infinispan-dev@lists.jboss.org >>> https://lists.jboss.org/mailman/listinfo/infinispan-dev >> > > > _______________________________________________ > infinispan-dev mailing list > infinispan-dev@lists.jboss.org > https://lists.jboss.org/mailman/listinfo/infinispan-dev -- Jason T. Greene JBoss, a division of Red Hat _______________________________________________ infinispan-dev mailing list infinispan-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/infinispan-dev