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?
On Tue, Dec 11, 2012 at 7:40 PM, David Holmes <david.hol...@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 >>>>>> >>>> >> >