1 #!/bin/sh 2 3 # 4 # Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. 5 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6 # 7 # This code is free software; you can redistribute it and/or modify it 8 # under the terms of the GNU General Public License version 2 only, as 9 # published by the Free Software Foundation. 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 # @test 27 # @bug 5002251 6407335 6412391 28 # @summary Redefine a class that has an annotation and verify that the 29 # new annotation is returned. 30 # 31 # @run shell RedefineAnnotation.sh 32 33 compileOptions=-g 34 35 # Uncomment this to see the JDI trace 36 #jdbOptions=-dbgtrace 37 38 createJavaFile() 39 { 40 cat <<EOF > $1.java.1 41 42 import java.lang.annotation.*; 43 import java.lang.reflect.*; 44 45 /** 46 */ 47 @Foo(Constants.class_annotation) // @1 commentout 48 // @1 uncomment @Foo(Constants.new_class_annotation) 49 public class $1 { 50 @Foo(Constants.field_annotation) // @1 commentout 51 // @1 uncomment @Foo(Constants.new_field_annotation) 52 public int dummy_field; 53 54 public static void main(String[] args) { 55 MySubClass sub = new MySubClass(); 56 MySubSubClass subsub = new MySubSubClass(); 57 new $1().hi(false); 58 new $1().hi(true); // @1 breakpoint 59 sub.hi(true); 60 subsub.hi(true); 61 } 62 63 @Foo(Constants.method_annotation) // @1 commentout 64 // @1 uncomment @Foo(Constants.new_method_annotation) 65 public void hi( 66 @Foo(Constants.method_parameter_annotation) // @1 commentout 67 // @1 uncomment @Foo(Constants.new_method_parameter_annotation) 68 boolean isNewVersion) { 69 70 if (isNewVersion) { 71 System.out.println("Checking for NEW versions of annotations in " 72 + getClass()); 73 } 74 75 // class annotations check: 76 Foo foo = getClass().getAnnotation(Foo.class); 77 if (foo == null) { 78 throw new Error("FAIL: cannot get class_annotation from " 79 + getClass()); 80 } 81 82 String class_annotation = foo.value(); 83 System.out.println("class annotation is: " + class_annotation); 84 if (isNewVersion) { 85 if (class_annotation.equals(Constants.new_class_annotation)) { 86 System.out.println("PASS: class_annotation was changed."); 87 } else { 88 System.out.println("FAIL: class_annotation was NOT changed."); 89 } 90 } 91 92 // field annotations check: 93 try { 94 Field my_field = getClass().getField("dummy_field"); 95 foo = my_field.getAnnotation(Foo.class); 96 if (foo == null) { 97 throw new Error("FAIL: cannot get field_annotation from " 98 + getClass() + ".dummy_field"); 99 } 100 String field_annotation = foo.value(); 101 System.out.println("field annotation is: " + field_annotation); 102 if (isNewVersion) { 103 if (field_annotation.equals(Constants.new_field_annotation)) { 104 System.out.println("PASS: field_annotation was changed."); 105 } else { 106 System.out.println( 107 "FAIL: field_annotation was NOT changed."); 108 } 109 } 110 } catch (NoSuchFieldException nsfe) { 111 throw new Error("FAIL: cannot find field 'dummy_field' in " 112 + getClass()); 113 } 114 115 // method annotations check: 116 try { 117 Class params[] = new Class[1]; 118 params[0] = Boolean.TYPE; 119 Method my_method = getClass().getMethod("hi", params); 120 foo = my_method.getAnnotation(Foo.class); 121 if (foo == null) { 122 throw new Error("FAIL: cannot get field_annotation from " 123 + getClass() + ".hi()"); 124 } 125 String method_annotation = foo.value(); 126 System.out.println("method annotation is: " + method_annotation); 127 if (isNewVersion) { 128 if (method_annotation.equals(Constants.new_method_annotation)) { 129 System.out.println("PASS: method_annotation was changed."); 130 } else { 131 System.out.println( 132 "FAIL: method_annotation was NOT changed."); 133 } 134 } 135 } catch (NoSuchMethodException nsme) { 136 throw new Error("FAIL: cannot find method 'hi' in " + getClass()); 137 } 138 139 // method parameter annotations check: 140 try { 141 Class params[] = new Class[1]; 142 params[0] = Boolean.TYPE; 143 Method my_method = getClass().getMethod("hi", params); 144 Annotation my_annotations[][] = my_method.getParameterAnnotations(); 145 if (my_annotations.length != 1) { 146 throw new Error("FAIL: unexpected my_annotations.length (" 147 + my_annotations.length); 148 } 149 Annotation my_annotation[] = my_annotations[0]; 150 if (my_annotation.length != 1) { 151 throw new Error("FAIL: unexpected my_annotation.length (" 152 + my_annotation.length); 153 } 154 foo = (Foo)my_annotation[0]; 155 String method_parameter_annotation = foo.value(); 156 System.out.println("method parameter annotation is: " 157 + method_parameter_annotation); 158 if (isNewVersion) { 159 if (method_parameter_annotation.equals( 160 Constants.new_method_parameter_annotation)) { 161 System.out.println( 162 "PASS: method_parameter_annotation was changed."); 163 } else { 164 System.out.println( 165 "FAIL: method_parameter_annotation was NOT changed."); 166 } 167 } 168 } catch (NoSuchMethodException nsme) { 169 throw new Error("FAIL: cannot find method 'hi' in " + getClass()); 170 } 171 } 172 } 173 174 // this subclass exists just to make the RedefineClasses() code do a 175 // subclass walk to update the counter 176 class MySubClass extends $1 { 177 int my_int_field_makes_me_different; 178 } 179 180 // this subclass exists just to make the RedefineClasses() code do a 181 // sub-subclass walk to update the counter 182 class MySubSubClass extends MySubClass { 183 float my_float_field_makes_me_different; 184 } 185 186 class Constants { 187 static final String class_annotation = "Patrick's class comment"; 188 static final String new_class_annotation = "*NEW* Patrick's class comment"; 189 190 static final String field_annotation = "dummy_field comment"; 191 static final String new_field_annotation = "*NEW* dummy_field comment"; 192 193 static final String method_annotation = "method hi() comment"; 194 static final String new_method_annotation = "*NEW* method hi() comment"; 195 196 static final String method_parameter_annotation = 197 "param isNewVersion comment"; 198 static final String new_method_parameter_annotation = 199 "*NEW* param isNewVersion comment"; 200 } 201 202 203 /** 204 */ 205 @Retention(RetentionPolicy.RUNTIME) 206 @Inherited 207 @interface Foo { 208 String value(); 209 } 210 211 EOF 212 } 213 214 # This is called to feed cmds to jdb. 215 dojdbCmds() 216 { 217 setBkpts @1 218 runToBkpt @1 219 redefineClass @1 220 cmd allowExit cont 221 } 222 223 224 mysetup() 225 { 226 if [ -z "$TESTSRC" ] ; then 227 TESTSRC=. 228 fi 229 230 for ii in . $TESTSRC $TESTSRC/.. ; do 231 if [ -r "$ii/ShellScaffold.sh" ] ; then 232 . $ii/ShellScaffold.sh 233 break 234 fi 235 done 236 } 237 238 # You could replace this next line with the contents 239 # of ShellScaffold.sh and this script will run just the same. 240 mysetup 241 242 runit 243 244 debuggeeFailIfPresent 'FAIL:' 245 pass