Access Modifier Issues

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Fri Jan 9 15:11:05 UTC 2015


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
>
>>
>> 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