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