[infinispan-dev] [Pull Request] Modular Classloading Compatibility

David M. Lloyd david.lloyd at redhat.com
Wed May 4 11:14:19 EDT 2011


On 05/04/2011 09:08 AM, Pete Muir wrote:
> 
> On 4 May 2011, at 09:55, Dan Berindei wrote:
> 
>> On Wed, May 4, 2011 at 7:18 AM, "이희승 (Trustin
>> Lee)"<trustin at gmail.com>  wrote:
>>> On 05/03/2011 09:33 PM, Sanne Grinovero wrote:
>>>> 2011/5/3 "이희승 (Trustin Lee)"<trustin at gmail.com>:
>>>>> On 05/03/2011 05:08 AM, Sanne Grinovero wrote:
>>>>>> 2011/5/2 Manik Surtani<manik at 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 :)
>>> 
>>> By default, we could use the class loader that the current
>>> Unmarshaller uses, and let user choose a class loader for a
>>> certain get() call.
>>> 
>>> So, we need to deal with the two issues here:
>>> 
>>> 1) Make sure that user can configure the default class loader in
>>> runtime and calling get() (and consequently related unmarshaller)
>>> will use the default class loader:
>>> 
>>> cache.setDefaultClassLoader(UserClass.class.getClassLoader())
>>> 
>>> 2) Provide an additional API that allows a user to specify a
>>> class loader for the current transaction or context:
>>> 
>>> cache.get(K key, Class<V>  clazz) // +1 to Pete's suggestion
>>> 
>> 
>> If V is Set<MyObject>  then Set<MyObject>.class.getClassLoader()
>> will give you the system classloader, which in most cases won't be
>> able the MyObject class. It may not even be a Set<MyObject>  of
>> course, it could be just Set<?>.
>> 
>> We could have a "shortcut" so the users can pass in a class instead
>> of a classloader to avoid writing ".getClassLoader()", but we
>> shouldn't require any relation between the class passed in and the
>> class of the return value.
> 
> There are two forces at play here. Firstly the desire to introduce
> greater type safety into the Cache API, by returning a type for user,
> rather than just an object, and secondly the need to specify the CL.
> 
> We could have an API like:
> 
> <V, CL>  V get(Object key, Class<CL>  classLoaderType);

See note below about the CL type parameter.

> and an overloaded form
> 
> <V>  V get(Object key, ClassLoader cl);
> 
> This does involve Infinispan having to do a runtime cast to V without
> the class type passed in as a parameter, but this may be a necessary
> evil in the interest of improving the user api.

There's no reason to do the runtime cast.  This should be spelled:

Object get(Object key, ClassLoader cl);

That way if there's a CCE, the user will stand a better chance of
understanding it (because hey, they did a cast).

> An alternative which is somewhat more verbose, somewhat safer, and
> somewhat more complex to explain (but ultimately more logical):
> 
> // Use the classloader of the expectedType, this would be the normal
> case <V>  V get(Object key, Class<V>  expectedType);
> 
> // Specify the classloader to use as a class
> <V, CL>  V get(Object key, Class<V>  expectedType, Class<CL>
classLoader);

This one doesn't make a lot of sense to me.  In particular there's no
reason to have a type parameter CL unless you give it a bound in
relationship to V, in which case you could have just used the class
loader class in the first place.  Maybe you meant:

<V> V get(Object key, Class<V> expected, Class<?>
classWhoseClassLoaderShouldBeUsed);

And I would name that parameter exactly thus :)

> // Specify the classloader to use as a classloader 
> <V>  V get(Object key, Class<V>  expectedType, ClassLoader classLoader);
> 
> We could also include
> 
> // Use the TCCL
> V get(Object key);

Or a preset default CL?

-- 
- DML


More information about the infinispan-dev mailing list