Proposal: Fully Concurrent ClassLoading

Zhong Yu zhong.j.yu at gmail.com
Wed Dec 12 16:24:05 UTC 2012


On Wed, Dec 12, 2012 at 10:05 AM, Peter Levart <peter.levart at gmail.com> wrote:
> On 12/12/2012 04:51 PM, Zhong Yu wrote:
>>
>> If a class loader is declared fully concurrent, yet
>> getClassLoadingLock() is invoked, what's the harm of returning a
>> dedicated lock anyway, exactly like what's done before?
>
> To encourage people to not use locking in the first place ;-)

In that case throwing an exception is probably better than returning a null.

> No, seriously, to be able to remove the deprecated feature in the future,
> perhaps.

> Peter
>
>>
>> On Tue, Dec 11, 2012 at 7:40 PM, David Holmes <david.holmes at oracle.com>
>> wrote:
>>>
>>> On 11/12/2012 9:58 PM, Peter Levart wrote:
>>>>
>>>> On 12/11/2012 12:27 PM, David Holmes wrote:
>>>>>
>>>>> Peter,
>>>>>
>>>>> You are convincing me that all superclasses must be fully concurrent
>>>>> too. Otherwise we are just trying to second-guess a whole bunch of
>>>>> what-ifs. :)
>>>>
>>>>
>>>> If you think some more, yes. The superclass might not use
>>>> getClassLoadingLock() but rely on the fact that findClass() is allways
>>>> called under a guard of per-class-name lock, for example. It's a matter
>>>> of how far to go to prevent such miss-behaving fully-concurrent
>>>> subclasses. So far to also prevent fully-concurrent subclasses that
>>>> would otherwise be perfectly correct?
>>>>
>>>> Maybe not. Creating custom ClassLoaders is not an average programmer's
>>>> job. Those that do this things will of course study the implementations
>>>> of superclasses they extend and do the right thing. And it's reasonable
>>>> to expect that they more or less will only extend JDK's ClassLoaders -
>>>> but on the other hand if they only extend JDK's class loaders, they are
>>>> not prevented to be fully-concurrent either way. Hm...
>>>
>>>
>>> Again I think it is just too hard to try and second-guess how a
>>> parallel-loader might rely on the per-class locks (I actually don't see
>>> any
>>> reasonable use for them beyond flow-control), and then how a concurrent
>>> loader subclass might need to modify things.
>>>
>>> If we simply disallow this then we can relax that constraint in the
>>> future
>>> if valid use-cases turn up for that capability. Of course if someone has
>>> a
>>> valid use-case during this discussion phase then of course that will
>>> influence the decision.
>>>
>>> Thanks,
>>> David
>>>
>>>> Peter
>>>>
>>>>> Thanks,
>>>>> David
>>>>>
>>>>> On 11/12/2012 7:44 PM, Peter Levart wrote:
>>>>>>
>>>>>> On 12/11/2012 10:29 AM, David Holmes wrote:
>>>>>>>
>>>>>>> On 11/12/2012 7:20 PM, Peter Levart wrote:
>>>>>>>>
>>>>>>>> On 12/11/2012 03:55 AM, David Holmes wrote:
>>>>>>>>>>
>>>>>>>>>> Question on the source code: registerAsFullyConcurrent has
>>>>>>>>>> confusing
>>>>>>>>>> comment -
>>>>>>>>>> do the super classes all need to be parallel capable? Or do the
>>>>>>>>>> super
>>>>>>>>>> classes all need
>>>>>>>>>> to be FullyConcurrent? I assume the latter, so just fix the
>>>>>>>>>> comments.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Actually it is the former. There's no reason to require that all
>>>>>>>>> superclasses be fully-concurrent. Of course a given loaders degree
>>>>>>>>> of
>>>>>>>>> concurrency may be constrained by what it's supertype allows, but
>>>>>>>>> there's no reason to actually force all the supertypes to be
>>>>>>>>> fully-concurrent: it is enough that they are at least all parallel
>>>>>>>>> capable.
>>>>>>>>
>>>>>>>>
>>>>>>>> Hi David,
>>>>>>>>
>>>>>>>> There is one caveat: if ClassLoader X declares that it is
>>>>>>>> fully-concurrent and it's superclass Y is only parallel-capable,
>>>>>>>> then X
>>>>>>>> will act as fully-concurrent (returning null from
>>>>>>>> getClassLoadingLock()). superclass Y might or might not be coded to
>>>>>>>> use
>>>>>>>> the getClassLoadingLock(). X therefore has to know how Y is coded.
>>>>>>>> To be
>>>>>>>> defensive, X could ask for Y's registration and declare itself as
>>>>>>>> only
>>>>>>>> parallel-capable if Y declares the same so that when Y is upgraded
>>>>>>>> to be
>>>>>>>> fully-concurrent, X would become fully-concurrent automatically. To
>>>>>>>> support situations where the same version of X would work in two
>>>>>>>> environments where in one Y is only parallel-capable and in the
>>>>>>>> other Y
>>>>>>>> is fully-concurrent, there could be a static API to retrieve the
>>>>>>>> registrations of superclasses.
>>>>>>>
>>>>>>>
>>>>>>> I don't quite follow this. What code in the superclass are you
>>>>>>> anticipating that the subclass will use which relies on the lock? Or
>>>>>>> is this just an abstract "what if" scenario?
>>>>>>
>>>>>>
>>>>>> This is more or less "what if". There might be a subclass Y of say
>>>>>> java.lang.ClassLoader that overrides loadClass or findClass, declares
>>>>>> that it is parallel-capable and in the implementation of it's
>>>>>> loadClass
>>>>>> or findClass, uses getClassLoadingLock() to synchronize access to it's
>>>>>> internal state. Now there comes class X extends Y that declares that
>>>>>> it
>>>>>> is fully-concurrent. Of course this will not work, X has to declare
>>>>>> that
>>>>>> it is parallel-capable, because Y uses getClassLoadingLock().
>>>>>>
>>>>>> What I suggested in the next message is to not change the registration
>>>>>> API but rather provide getClassLoadingLock() that returns non-null
>>>>>> locks
>>>>>> when any of the superclasses declare that they are only
>>>>>> parallel-capable, not fully-concurrent.
>>>>>>
>>>>>> Regards, Peter
>>>>>>
>>>>>>> Thanks,
>>>>>>> David
>>>>>>> -----
>>>>>>>
>>>>>>>> Or, to have less impact on future deprecation of old
>>>>>>>> parallel-capable
>>>>>>>> registration API, the fully-concurrent registration API:
>>>>>>>>
>>>>>>>> protected static boolean registerAsFullyConcurrent()
>>>>>>>>
>>>>>>>> might take a boolean parameter:
>>>>>>>>
>>>>>>>> protected static boolean registerAsFullyConcurrent(boolean
>>>>>>>> downgradeToPrallelCapableIfAnySuperclassIsNotFullyConcurrent)
>>>>>>>>
>>>>>>>>
>>>>>>>> and provide no accessible API to find out what the registration
>>>>>>>> actually
>>>>>>>> did (register as parallel-capable or fully-concurrent - return true
>>>>>>>> in
>>>>>>>> any case).
>>>>>>>>
>>>>>>>> Since all JDK provided ClassLoaders will be made fully concurrent,
>>>>>>>> this
>>>>>>>> might only be relevant if there is vendor A that currently provides
>>>>>>>> only
>>>>>>>> parallel-capable ClassLoader implementation and there is vendor B
>>>>>>>> that
>>>>>>>> subclasses A's loader and wants to upgrade and be backward
>>>>>>>> compatible at
>>>>>>>> the same time.
>>>>>>>>
>>>>>>>> Does this complicate things to much for no real benefit?
>>>>>>>>
>>>>>>>> Regards, Peter
>>>>>>>>
>



More information about the core-libs-dev mailing list