Path: blob/master/test/jdk/java/lang/Class/getSimpleName/GetSimpleNameTest.java
41155 views
/*1* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 805791925* @summary Class.getSimpleName() should work for non-JLS compliant class names26* @modules java.base/jdk.internal.org.objectweb.asm27*/28import jdk.internal.org.objectweb.asm.*;29import static jdk.internal.org.objectweb.asm.Opcodes.*;3031public class GetSimpleNameTest {32static class NestedClass {}33class InnerClass {}3435static Class<?> f1() {36class LocalClass {}37return LocalClass.class;38}3940public static void main(String[] args) throws Exception {41assertEquals(NestedClass.class.getSimpleName(), "NestedClass");42assertEquals( InnerClass.class.getSimpleName(), "InnerClass");43assertEquals( f1().getSimpleName(), "LocalClass");4445java.io.Serializable anon = new java.io.Serializable() {};46assertEquals(anon.getClass().getSimpleName(), "");4748// Java class names, prepended enclosing class name.49testNested("p.Outer$Nested", "p.Outer", "Nested");50testInner( "p.Outer$Inner", "p.Inner", "Inner");51testLocal( "p.Outer$1Local", "p.Outer", "Local");52testAnon( "p.Outer$1", "p.Outer", "");5354// Non-Java class names, prepended enclosing class name.55testNested("p.$C1$Nested", "p.$C1$", "Nested");56testInner( "p.$C1$Inner", "p.$C1$", "Inner");57testLocal( "p.$C1$Local", "p.$C1$", "Local");58testAnon( "p.$C1$1", "p.$C1$", "");5960// Non-Java class names, unrelated class names.61testNested("p1.$Nested$", "p2.$C1$", "Nested");62testInner( "p1.$Inner$", "p2.$C1$", "Inner");63testLocal( "p1.$Local$", "p2.$C1$", "Local");64testAnon( "p1.$anon$", "p2.$C1$", "");65}6667static void testNested(String innerName, String outerName, String simpleName) throws Exception {68BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName);69CustomCL cl = new CustomCL(innerName, outerName, bg.getNestedClasses(true), bg.getNestedClasses(false));70assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName);71}7273static void testInner(String innerName, String outerName, String simpleName) throws Exception {74BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName);75CustomCL cl = new CustomCL(innerName, outerName, bg.getInnerClasses(true), bg.getInnerClasses(false));76assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName);77}7879static void testLocal(String innerName, String outerName, String simpleName) throws Exception {80BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName);81CustomCL cl = new CustomCL(innerName, outerName, bg.getLocalClasses(true), bg.getLocalClasses(false));82assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName);83}8485static void testAnon(String innerName, String outerName, String simpleName) throws Exception {86BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName);87CustomCL cl = new CustomCL(innerName, outerName, bg.getAnonymousClasses(true), bg.getAnonymousClasses(false));88assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName);89}9091static void assertEquals(Object o1, Object o2) {92if (!java.util.Objects.equals(o1, o2)) {93throw new AssertionError(o1 + " != " + o2);94}95}9697static class CustomCL extends ClassLoader {98final String innerName;99final String outerName;100101final byte[] innerClassFile;102final byte[] outerClassFile;103104CustomCL(String innerName, String outerName, byte[] innerClassFile, byte[] outerClassFile) {105this.innerName = innerName;106this.outerName = outerName;107this.innerClassFile = innerClassFile;108this.outerClassFile = outerClassFile;109}110@Override111protected Class<?> findClass(String name) throws ClassNotFoundException {112if (innerName.equals(name)) {113return defineClass(innerName, innerClassFile, 0, innerClassFile.length);114} else if (outerName.equals(name)) {115return defineClass(outerName, outerClassFile, 0, outerClassFile.length);116} else {117throw new ClassNotFoundException(name);118}119}120}121122static class BytecodeGenerator {123final String innerName;124final String outerName;125final String simpleName;126127BytecodeGenerator(String innerName, String outerName, String simpleName) {128this.innerName = intl(innerName);129this.outerName = intl(outerName);130this.simpleName = simpleName;131}132133static String intl(String name) { return name.replace('.', '/'); }134135static void makeDefaultCtor(ClassWriter cw) {136MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);137mv.visitCode();138mv.visitVarInsn(ALOAD, 0);139mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);140mv.visitInsn(RETURN);141mv.visitMaxs(1, 1);142mv.visitEnd();143}144145void makeCtxk(ClassWriter cw, boolean isInner) {146if (isInner) {147cw.visitOuterClass(outerName, "f", "()V");148} else {149MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "f", "()V", null, null);150mv.visitCode();151mv.visitInsn(RETURN);152mv.visitMaxs(0, 0);153mv.visitEnd();154}155}156157byte[] getNestedClasses(boolean isInner) {158String name = (isInner ? innerName : outerName);159ClassWriter cw = new ClassWriter(0);160cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, name, null, "java/lang/Object", null);161162cw.visitInnerClass(innerName, outerName, simpleName, ACC_PUBLIC | ACC_STATIC);163164makeDefaultCtor(cw);165cw.visitEnd();166return cw.toByteArray();167}168169byte[] getInnerClasses(boolean isInner) {170String name = (isInner ? innerName : outerName);171ClassWriter cw = new ClassWriter(0);172cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, name, null, "java/lang/Object", null);173174cw.visitInnerClass(innerName, outerName, simpleName, ACC_PUBLIC);175176makeDefaultCtor(cw);177cw.visitEnd();178return cw.toByteArray();179}180181byte[] getLocalClasses(boolean isInner) {182String name = (isInner ? innerName : outerName);183ClassWriter cw = new ClassWriter(0);184cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, name, null, "java/lang/Object", null);185186cw.visitInnerClass(innerName, null, simpleName, ACC_PUBLIC | ACC_STATIC);187makeCtxk(cw, isInner);188189makeDefaultCtor(cw);190cw.visitEnd();191return cw.toByteArray();192}193194byte[] getAnonymousClasses(boolean isInner) {195String name = (isInner ? innerName : outerName);196ClassWriter cw = new ClassWriter(0);197cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, name, null, "java/lang/Object", null);198199cw.visitInnerClass(innerName, null, null, ACC_PUBLIC | ACC_STATIC);200makeCtxk(cw, isInner);201202makeDefaultCtor(cw);203cw.visitEnd();204return cw.toByteArray();205}206}207}208209210