1/* 2 * Copyright (c) 2014, 2015, 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 24/* 25 * @test 26 * @bug 8028553 27 * @summary Test that VerifyError is not thrown when 'overriding' a static method. 28 * @modules java.base/jdk.internal.org.objectweb.asm 29 * @run main FinalStatic 30 */ 31 32import java.lang.reflect.*; 33import jdk.internal.org.objectweb.asm.ClassWriter; 34import jdk.internal.org.objectweb.asm.MethodVisitor; 35import jdk.internal.org.objectweb.asm.Opcodes; 36 37/* 38 * class A { static final int m() {return FAIL; } } 39 * class B extends A { int m() { return PASS; } } 40 * class FinalStatic { 41 * public static void main () { 42 * Object b = new B(); 43 * b.m(); 44 * } 45 * } 46 */ 47public class FinalStatic { 48 49 static final String CLASS_NAME_A = "A"; 50 static final String CLASS_NAME_B = "B"; 51 static final int FAILED = 0; 52 static final int EXPECTED = 1234; 53 54 static class TestClassLoader extends ClassLoader implements Opcodes { 55 56 @Override 57 public Class findClass(String name) throws ClassNotFoundException { 58 byte[] b; 59 try { 60 b = loadClassData(name); 61 } catch (Throwable th) { 62 // th.printStackTrace(); 63 throw new ClassNotFoundException("Loading error", th); 64 } 65 return defineClass(name, b, 0, b.length); 66 } 67 68 private byte[] loadClassData(String name) throws Exception { 69 ClassWriter cw = new ClassWriter(0); 70 MethodVisitor mv; 71 switch (name) { 72 case CLASS_NAME_A: 73 cw.visit(52, ACC_SUPER | ACC_PUBLIC, CLASS_NAME_A, null, "java/lang/Object", null); 74 { 75 mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); 76 mv.visitCode(); 77 mv.visitVarInsn(ALOAD, 0); 78 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); 79 mv.visitInsn(RETURN); 80 mv.visitMaxs(1, 1); 81 mv.visitEnd(); 82 83 mv = cw.visitMethod(ACC_FINAL | ACC_STATIC, "m", "()I", null, null); 84 mv.visitCode(); 85 mv.visitLdcInsn(FAILED); 86 mv.visitInsn(IRETURN); 87 mv.visitMaxs(1, 1); 88 mv.visitEnd(); 89 } 90 break; 91 case CLASS_NAME_B: 92 cw.visit(52, ACC_SUPER | ACC_PUBLIC, CLASS_NAME_B, null, CLASS_NAME_A, null); 93 { 94 mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); 95 mv.visitCode(); 96 mv.visitVarInsn(ALOAD, 0); 97 mv.visitMethodInsn(INVOKESPECIAL, CLASS_NAME_A, "<init>", "()V"); 98 mv.visitInsn(RETURN); 99 mv.visitMaxs(1, 1); 100 mv.visitEnd(); 101 102 mv = cw.visitMethod(ACC_PUBLIC, "m", "()I", null, null); 103 mv.visitCode(); 104 mv.visitLdcInsn(EXPECTED); 105 mv.visitInsn(IRETURN); 106 mv.visitMaxs(1, 1); 107 mv.visitEnd(); 108 109 } 110 break; 111 default: 112 break; 113 } 114 cw.visitEnd(); 115 116 return cw.toByteArray(); 117 } 118 } 119 120 public static void main(String[] args) throws Exception { 121 TestClassLoader tcl = new TestClassLoader(); 122 Class<?> a = tcl.loadClass(CLASS_NAME_A); 123 Class<?> b = tcl.loadClass(CLASS_NAME_B); 124 Object inst = b.newInstance(); 125 Method[] meths = b.getDeclaredMethods(); 126 127 Method m = meths[0]; 128 int mod = m.getModifiers(); 129 if ((mod & Modifier.FINAL) != 0) { 130 throw new Exception("FAILED: " + m + " is FINAL"); 131 } 132 if ((mod & Modifier.STATIC) != 0) { 133 throw new Exception("FAILED: " + m + " is STATIC"); 134 } 135 136 m.setAccessible(true); 137 if (!m.invoke(inst).equals(EXPECTED)) { 138 throw new Exception("FAILED: " + EXPECTED + " from " + m); 139 } 140 141 System.out.println("Passed."); 142 } 143} 144