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