1 /* 2 * Copyright (c) 2016, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * Create class file using ASM, slightly modified the ASMifier output 28 */ 29 30 31 32 import java.io.File; 33 import java.io.FileOutputStream; 34 import java.io.IOException; 35 import jdk.internal.org.objectweb.asm.*; 36 37 38 public class ClassFileGenerator { 39 40 public static void main(String... args) throws Exception { 41 classFileWriter("AnnoationWithVoidReturn.class", AnnoationWithVoidReturnDump.dump()); 42 classFileWriter("AnnoationWithParameter.class", AnnoationWithParameterDump.dump()); 43 } 44 45 private static void classFileWriter(String name, byte[] contents) throws IOException { 46 try (FileOutputStream fos = new FileOutputStream(new File(System.getProperty("test.classes"), 47 name))) { 48 fos.write(contents); 49 } 50 } 51 52 /* 53 Following code create equivalent classfile, 54 which is not allowed by javac. 55 @Retention(RetentionPolicy.RUNTIME) 56 public @interface AnnoationWithVoidReturn { 57 void m() default 1; 58 } 59 */ 60 61 private static class AnnoationWithVoidReturnDump implements Opcodes { 62 public static byte[] dump() throws Exception { 63 ClassWriter cw = new ClassWriter(0); 64 MethodVisitor mv; 65 AnnotationVisitor av0; 66 67 cw.visit(52, ACC_PUBLIC + ACC_ANNOTATION + ACC_ABSTRACT + +ACC_INTERFACE, 68 "AnnoationWithVoidReturn", null, 69 "java/lang/Object", new String[]{"java/lang/annotation/Annotation"}); 70 71 { 72 av0 = cw.visitAnnotation("Ljava/lang/annotation/Retention;", true); 73 av0.visitEnum("value", "Ljava/lang/annotation/RetentionPolicy;", 74 "RUNTIME"); 75 av0.visitEnd(); 76 } 77 { 78 mv = cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "m", "()V", null, null); 79 mv.visitEnd(); 80 } 81 { 82 av0 = mv.visitAnnotationDefault(); 83 av0.visit(null, new Integer(1)); 84 av0.visitEnd(); 85 } 86 cw.visitEnd(); 87 88 return cw.toByteArray(); 89 90 } 91 } 92 93 /* 94 Following code create equivalent classfile, 95 which is not allowed by javac. 96 @Retention(RetentionPolicy.RUNTIME) 97 public @interface AnnoationWithParameter { 98 int m(int x); 99 } 100 */ 101 102 private static class AnnoationWithParameterDump implements Opcodes { 103 public static byte[] dump() throws Exception { 104 105 ClassWriter cw = new ClassWriter(0); 106 MethodVisitor mv; 107 AnnotationVisitor av0; 108 109 cw.visit(52, ACC_PUBLIC + ACC_ANNOTATION + ACC_ABSTRACT + ACC_INTERFACE, 110 "AnnoationWithParameter", null, 111 "java/lang/Object", new String[]{"java/lang/annotation/Annotation"}); 112 113 { 114 av0 = cw.visitAnnotation("Ljava/lang/annotation/Retention;", true); 115 av0.visitEnum("value", "Ljava/lang/annotation/RetentionPolicy;", 116 "RUNTIME"); 117 av0.visitEnd(); 118 } 119 { 120 mv = cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, 121 "badValue", 122 "(I)I", // Bad method with a parameter 123 null, null); 124 mv.visitEnd(); 125 } 126 { 127 av0 = mv.visitAnnotationDefault(); 128 av0.visit(null, new Integer(-1)); 129 av0.visitEnd(); 130 } 131 cw.visitEnd(); 132 133 return cw.toByteArray(); 134 } 135 } 136 137 }