Access Modifier Issues

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Fri Jan 9 16:15:04 UTC 2015


On 09/01/15 16:09, Peter Levart wrote:
> On 01/09/2015 04:11 PM, Maurizio Cimadamore wrote:
>>
>> On 09/01/15 14:47, Peter Levart wrote:
>>> On 01/09/2015 03:11 PM, Richard Warburton wrote:
>>>> Hi gents,
>>>>
>>>> Not sure if its a high priority to fix the access modifier problems 
>>>> at the
>>>> moment, but there still seems to be a bug with Peter Levart's 
>>>> default hack
>>>> which I didn't see reported in the other thread.
>>>
>>> Yes, Maurizio already warned about currently buggy access to private 
>>> members from specialized methods. I think you can work-around by 
>>> using package-private access for the time being.
>> Exact. The underlying issue is a thorny one: the compiler is 
>> organized in 'phases', roughly as follows:
>>
>> source -> parse -> symbol enter -> type-checking -> flow analysis -> 
>> erasure -> lambda translation -> misc desugaring -> bytecode
>>
>> With specialization, the pipeline has been modified, so that an extra 
>> 'specialize' step is added before erasure takes place (it has to be 
>> like that, as we need to save full generic info in the AST).
>> The problem is that inner classes, accessibility and all desugaring 
>> is done in a later step (misc desugaring above) - meaning that for 
>> all the code generated there, there would be no way to generate the 
>> magic specialization attributes. Once you wrap your head around that, 
>> it's typically easy to fix the code in order to make it working again 
>> (i.e. in this case, tweak access) - of course this problem will be 
>> addressed in a more general way.
>>
>> Maurizio
>
> Hm, currently there seem to be two ways of triggering specialization. 
> First way is by referencing classes with specialy-crafted names 
> (SomeClass${0=?}) and ClassLoader then contains a hook to dispatch to 
> the specialization logic. The second is used for invoking specialized 
> generic methods, which works with invokedynamic and bootstrap methods. 
> Would theoretically be possible to replace the 1st way (special class 
> names) with the invokedynamic too? Would it be practical? Would it 
> solve access problems?
The current plan is to use a new mechanism called classdynamic for that 
purpose (this has come up before in this mailing list). I think, 
regardless on which plumbing you use to emit the generated class (either 
funky name + Loader changes, or classdyn), if the specialized class is a 
brand new class which is completely detached from the class it comes 
from, then access (w/o extra accessors) will always be problematic.

Maurizio
>
> Regards, Peter
>
>>>
>>>>
>>>> public class Default<any T> {
>>>>
>>>>      private T value;
>>>>
>>>>      private Default() {}
>>>>
>>>>      public static <any T> T value() {
>>>>          return new Default<T>().value;
>>>>      }
>>>>
>>>>      public static void main(String[] args) {
>>>>          int i = Default.value();
>>>>          System.out.println(i);
>>>>          long l = Default.value();
>>>>          System.out.println(l);
>>>>          Object o = Default.value();
>>>>          System.out.println(o);
>>>>      }
>>>>
>>>> }
>>>>
>>>> When running:
>>>>
>>>> Specializing method Default$value${0=I}.value()Ljava/lang/Object; with
>>>> class=[] and method=[I]
>>>> Specializing Default${0=I}; searching for Default.class (not found)
>>>> Specializing Default${0=I}; searching for Default.class (found)
>>>> Exception in thread "main" java.lang.IllegalAccessError: tried to 
>>>> access
>>>> method Default${0=I}.<init>()V from class 
>>>> Default$value${0=I}/793589513
>>>>          at Default$value${0=I}/793589513.value(Default.java:8)
>>>>          at Default.main(Default.java:12)
>>>>
>>>> Looks like its workaround-able by making both the constructor and 
>>>> value
>>>> field public.
>>>>
>>>> I think this also exposes something I don't understand here. My 
>>>> impression
>>>> was that "Default${0=I}" was the specialisation of the class 
>>>> Default s.t.
>>>> its first type parameter is an int. So what is "Default$value${0=I}"?
>>>
>>> I think Default$value${0=I}/793589513 is a special (VM-annonymous) 
>>> class, containing the specialization of static method 
>>> Default.value() for T=int.
>>>
>>> The problem seems to be that private constructor of specialized 
>>> class Default for T=int is not accessible from it. The specialized 
>>> static method does have access to private members of nonspecialized 
>>> class Default (since this is the host class of it's VM-anonymous 
>>> class where it is defined), but not to the specialized Default class 
>>> for T=int which is a separate class. Perhaps something similar to 
>>> how outer class has access to private members of inner classes and 
>>> vice-versa would have to be devised among non-specialized classes 
>>> and their specializations.
>>>
>>> Regards, Peter
>>>
>>>>
>>>> regards,
>>>>
>>>>    Richard Warburton
>>>>
>>>>    http://insightfullogic.com
>>>>    @RichardWarburto <http://twitter.com/richardwarburto>
>>>
>>
>




More information about the valhalla-dev mailing list