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

Reply via email to