test/runtime/lambda-features/TestConcreteClassWithAbstractMethod.java

Wed, 05 Feb 2014 15:14:47 -0800

author
ccheung
date
Wed, 05 Feb 2014 15:14:47 -0800
changeset 6308
a81bc2b2c4d3
parent 0
f90c822e73f8
permissions
-rw-r--r--

8032010: Attempt to resolve abstract method in concrete class fails with AbstractMethodError
Summary: removing a check in LinkResolver::resolve_method() to conform with a change in JVMS-8 5.4.3.3. Method Resolution
Reviewed-by: coleenp, lfoltan

     1 /*
     2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 /*
    26  * @test
    27  * @bug 8032010
    28  * @summary method lookup on an abstract method in a concrete class should be successful
    29  * @run main TestConcreteClassWithAbstractMethod
    30  */
    32 import jdk.internal.org.objectweb.asm.ClassWriter;
    33 import jdk.internal.org.objectweb.asm.MethodVisitor;
    35 import static jdk.internal.org.objectweb.asm.Opcodes.*;
    37 /*
    38  *   class T1 { public int m() {} }
    39  *   class T2 { public abstract int m(); }
    40  *   class T3 { public int m() {} }
    41  *
    42  *   Call site: T3.test() { invokevirtual T2.m() }
    43  *   T3.m() should be invoked
    44  */
    45 public class TestConcreteClassWithAbstractMethod {
    46     static final String classT1 = "p1.T1";
    47     static final String classT2 = "p1.T2";
    48     static final String classT3 = "p1.T3";
    50     static final String callerName = classT3;
    52     public static void main(String[] args) throws Exception {
    53         ClassLoader cl = new ClassLoader() {
    54             public Class<?> loadClass(String name) throws ClassNotFoundException {
    55                 if (findLoadedClass(name) != null) {
    56                     return findLoadedClass(name);
    57                 }
    59                 if (classT1.equals(name)) {
    60                     byte[] classFile = dumpT1();
    61                     return defineClass(classT1, classFile, 0, classFile.length);
    62                 }
    63                 if (classT2.equals(name)) {
    64                     byte[] classFile = dumpT2();
    65                     return defineClass(classT2, classFile, 0, classFile.length);
    66                 }
    67                 if (classT3.equals(name)) {
    68                     byte[] classFile = dumpT3();
    69                     return defineClass(classT3, classFile, 0, classFile.length);
    70                 }
    72                 return super.loadClass(name);
    73             }
    74         };
    76         cl.loadClass(classT1);
    77         cl.loadClass(classT2);
    78         cl.loadClass(classT3);
    80         //cl.loadClass(callerName).getDeclaredMethod("m");
    81         cl.loadClass(callerName).newInstance();
    83         int result = (Integer)cl.loadClass(callerName).getDeclaredMethod("test").invoke(null);
    84         System.out.println(""+result);
    85     }
    87     public static byte[] dumpT1() {
    88         ClassWriter cw = new ClassWriter(0);
    89         MethodVisitor mv;
    91         cw.visit(52, ACC_PUBLIC | ACC_SUPER, "p1/T1", null, "java/lang/Object", null);
    92         {
    93             mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    94             mv.visitCode();
    95             mv.visitVarInsn(ALOAD, 0);
    96             mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
    97             mv.visitInsn(RETURN);
    98             mv.visitMaxs(1, 1);
    99             mv.visitEnd();
   100         }
   101         {
   102             mv = cw.visitMethod(ACC_PUBLIC, "m", "()I", null, null);
   103             mv.visitCode();
   104             mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
   105             mv.visitLdcInsn("p1/T1.m()");
   106             mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V", false);
   107             mv.visitIntInsn(BIPUSH, 3);
   108             mv.visitInsn(IRETURN);
   109             mv.visitMaxs(2, 1);
   110             mv.visitEnd();
   111         }
   112         cw.visitEnd();
   114         return cw.toByteArray();
   115     }
   117     public static byte[] dumpT2() {
   118         ClassWriter cw = new ClassWriter(0);
   119         MethodVisitor mv;
   121         cw.visit(52, ACC_PUBLIC | ACC_SUPER, "p1/T2", null, "p1/T1", null);
   122         {
   123             mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
   124             mv.visitCode();
   125             mv.visitVarInsn(ALOAD, 0);
   126             mv.visitMethodInsn(INVOKESPECIAL, "p1/T1", "<init>", "()V", false);
   127             mv.visitInsn(RETURN);
   128             mv.visitMaxs(1, 1);
   129             mv.visitEnd();
   130         }
   131         {
   132             mv = cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "m", "()I", null, null);
   133             mv.visitEnd();
   134         }
   135         cw.visitEnd();
   137         return cw.toByteArray();
   138     }
   140     public static byte[] dumpT3() {
   141         ClassWriter cw = new ClassWriter(0);
   142         MethodVisitor mv;
   144         cw.visit(52, ACC_PUBLIC + ACC_SUPER, "p1/T3", null, "p1/T2", null);
   146         {
   147             mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
   148             mv.visitCode();
   149             mv.visitVarInsn(ALOAD, 0);
   150             mv.visitMethodInsn(INVOKESPECIAL, "p1/T2", "<init>", "()V", false);
   151             mv.visitInsn(RETURN);
   152             mv.visitMaxs(1, 1);
   153             mv.visitEnd();
   154         }
   155         {
   156             mv = cw.visitMethod(ACC_PUBLIC, "m", "()I", null, null);
   157             mv.visitCode();
   158             mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
   159             mv.visitLdcInsn("p1/T3.m()");
   160             mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V", false);
   161             mv.visitIntInsn(BIPUSH, 2);
   162             mv.visitInsn(IRETURN);
   163             mv.visitMaxs(2, 1);
   164             mv.visitEnd();
   165         }
   166         {
   167             mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "test", "()I", null, null);
   168             mv.visitCode();
   169             mv.visitTypeInsn(NEW, "p1/T3");
   170             mv.visitInsn(DUP);
   171             mv.visitMethodInsn(INVOKESPECIAL, "p1/T3", "<init>", "()V", false);
   172             mv.visitMethodInsn(INVOKEVIRTUAL, "p1/T2", "m", "()I", false);
   173             mv.visitInsn(IRETURN);
   174             mv.visitMaxs(3, 2);
   175             mv.visitEnd();
   176         }
   177         cw.visitEnd();
   179         return cw.toByteArray();
   180     }
   181 }

mercurial