On 12/12/2013 07:29 PM, Mandy Chung wrote:
JDK-8021368: Launch of Java Web Start app fails with ClassCircularityError exception in 7u25
https://bugs.openjdk.java.net/browse/JDK-8021368

This is a fix for 7u60 only. It's a regression in 7u25 due to JDK-8010117 where it calls Class.getMethod to determine if the checkMemberAccess method is overridden in a SecurityManager subclass but Class.getMethod causes parameter types and returned type of other public methods to be resolved and hence ClassCircularityError. It is not an issue in JDK 8 as SecurityManager.checkMemberAccess is deprecated and not called by the JDK (see JDK-8007035).

Webrev at:
http://cr.openjdk.java.net/~mchung/jdk7u/webrevs/8021368/webrev.00/

An alternative implementation is to add a new VM entry point to look up the declaring class of an overridden method instead of using JNI_GetMethodID and get a reflective method for a faster query. Since this check is only performed once in most cases, this performance cost of using JNI is not too bad that the new VM entry point doesn't necessarily buy much more.

thanks
Mandy

Hi Mandy,

I tried the following:


public class Test {

    static class A {}

    static class B {}

    static class X {
        public void x() { }
    }

    static class Y extends X {
        public A a(B b) { return null; }
        public B b(A a) { return null; }
        public void x() { }
    }

    public static void main(String[] args) throws Exception {
        MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.findVirtual(Y.class, "x", MethodType.methodType(void.class, new Class[0]));
        MethodHandleInfo mhi = lookup.revealDirect(mh);
        System.out.println(mhi.getDeclaringClass() == Y.class);
    }
}


The above code does not trigger loading of classes A or B. But unfortunately it prints true even if I comment-out the declaration of method Y.x(). I don't know if this is a bug though. I should ask on the mlvm-dev list...

Anyway, your approach seems more appropriate as it doesn't depend on method handles and their peculiarities...

Some nits:

2241      * Finds the checkMemberAccess method of the given 
SecurityManager*instance*.


...I think it should read "...of the given SecurityManager*class*." instead, 
since the method parameter is of type Class.


2210     private static class SecurityManagerHelper {
2211         private final SecurityManager smgr;
2212         private final boolean overrideCheckMemberAccess;


...the fields could be declared package-private so that no synthetic access 
methods are generated...


Regards, Peter

Reply via email to