On Wed, May 4, 2011 at 5:09 PM, Pete Muir <pmuir(a)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 <galder(a)redhat.com> wrote:
>>
>> On May 3, 2011, at 2:33 PM, Sanne Grinovero wrote:
>>
>>> 2011/5/3 "이희승 (Trustin Lee)" <trustin(a)gmail.com>:
>>>> On 05/03/2011 05:08 AM, Sanne Grinovero wrote:
>>>>> 2011/5/2 Manik Surtani <manik(a)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.