Can't instantiate anonymous class more than 16 times

Wei Yin Teo weiyinteo at gmail.com
Tue Aug 11 14:14:25 PDT 2009


I tried both: true and false. :)

In fact, setting it to true would fail the first time. In  
ReflectionFactory.newConstructorAccessor, we have

         if (noInflation) {
             return new MethodAccessorGenerator().
                 generateConstructor(c.getDeclaringClass(),
                                     c.getParameterTypes(),
                                     c.getExceptionTypes(),
                                     c.getModifiers());
         } else {
             NativeConstructorAccessorImpl acc =
                 new NativeConstructorAccessorImpl(c);
             DelegatingConstructorAccessorImpl res =
                 new DelegatingConstructorAccessorImpl(acc);
             acc.setParent(res);
             return res;
         }

We get the generated bytecode constructor the first time instead when  
the threshold is exceeded.


On 11 Aug 2009, at 21:47, Rémi Forax wrote:

> Le 11/08/2009 21:03, Wei Yin Teo a écrit :
>>
>>
>>
>> On 11 Aug 2009, at 02:09, Rémi Forax wrote:
>>
>>> Le 11/08/2009 00:49, Wei Yin Teo a écrit :
>>>>
>>>> Right, I think the work around is working because we are getting  
>>>> a new class and we don't hit the threshold.
>>>>
>>>> The magic number 15 is the ReflectionFactory.inflationThreshold()  
>>>> as we can see in the class NativeConstructorAccessorImpl
>>>>
>>>>
>>>>  public Object newInstance(Object[] args) ...    {
>>>>         if (++numInvocations >  
>>>> ReflectionFactory.inflationThreshold()) {
>>>>             ConstructorAccessorImpl acc = (ConstructorAccessorImpl)
>>>>                 new MethodAccessorGenerator().
>>>>                     generateConstructor(...)
>>>>  ...
>>>>
>>>> I think the AnonymousClassLoader mangles the class name from  
>>>> InstanceTest to InstanceTest/123456. However the generated  
>>>> ConstructorAccessor would interpret that as a class InstanceTest. 
>>>> 123456 instead of InstanceTest and the JVM would then try to load  
>>>> InstanceTest/123456.class. Of course it can't be found anywhere.  
>>>> I suppose Class.forName() should not be able to locate it in the  
>>>> system(permGen?) name space, either.
>>>
>>> You're right the problem is in package sun.reflect but the problem  
>>> is not
>>> a dot transformed to a slash or vice-versa.
>>>
>>> Class.forName() uses class loader mechanism, and anonymous class  
>>> aren't registered
>>> in any classloader cache. The reflection factory (here  
>>> MethodAccessorGenerator)
>>> generates a bytecode with the name of the anonymous class in the  
>>> constant pool
>>> to be able to call the constructor of the anonymous class.
>>> When this bytecode is loaded, the VM tries to resolve it with a  
>>> classloader mechanism,
>>> so it fails throwing a NoClassDefFound.
>>>
>>> So, short time workaround:
>>> use -Dsun.reflect.noInflation=false
>>
>> Apparently, this doesn't work as you can see the above  
>> newInstance(..) calls  
>> MethodAccessorGenerator().generateConstructor(...) when the  
>> threshold is exceeded. Shouldn't it call  
>> ReflectionFactory.newConstructorAccessor(), which is guarded by the  
>> system property, instead?
>
> oup, sorry
> -Dsun.reflect.noInflation=true
>
> Rémi
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20090811/ae733a31/attachment.html 


More information about the mlvm-dev mailing list