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@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

Reply via email to