1#!/bin/sh
2
3#
4# Copyright (c) 2002, 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 4724076
28#  @summary Redefine does not work in for/while loop
29#  @author Jim Holmlund/Swamy Venkataramanappa
30#
31#  The failure occurs when a method is active and
32#  a method that it calls multiple times is redefined
33#  more than once.
34#  @run shell/timeout=240 RedefineMulti.sh
35
36compileOptions=-g
37#java=java_g
38
39createJavaFile()
40{
41    cat <<EOF > $1.java.1
42
43public class $1 {
44
45    String field1;
46    String field2;
47
48    // The first time thru the loop in start,
49    // "Before update..." should be printed.
50    // After the first redefine, "After update..." should be printed
51    // After the 2nd redefine, "abcde..." should be printed.
52    // The bug is that "After update..." is printed instead because
53    // stat() calls version 2 of doSomething() instead of
54    // version 3.
55    private void doSomething()  {
56        System.out.println("Before update...");  // @1 commentout
57        // @1 uncomment System.out.println("After update...");  // @2 commentout
58        // @2 uncomment System.out.println("abcde...");
59    }
60
61    public void start() {
62        for (int i=0; i < 3; i++)   {
63            doSomething();      // @1 breakpoint here  line 16
64            System.out.println("field1 = " + field1);
65            System.out.println("field2 = " + field2);
66        }
67        // Redefinex myx = new Redefinex();
68        //  for (int i = 0; i < 5; i++) {
69        //    myx.methodx1();                     // line 22
70        //    System.out.println("fieldx1 = " + myx.fieldx1);
71        //    System.out.println("fieldx2 = " + myx.fieldx2);
72        //  }
73    }
74
75    public static void main(String[] args) {
76        $1 xxx = new $1();
77        xxx.field1 = "field1";
78        xxx.field2 = "field2";
79        xxx.start();
80    }
81}
82
83class Redefinex {
84    public String fieldx1;
85    public String fieldx2;
86
87    Redefinex() {
88        fieldx1 = "fieldx1";
89        fieldx2 = "fieldx2";
90    }
91
92    public void methodx1() {
93        System.out.println("redefinex 1");
94        //System.out.println("redefinex 2");
95        //System.out.println("redefinex 3");
96    }
97     
98}
99
100    /*********
101Steps to reproduce this problem:
102   a. add line breakpoint  in start()
103   b. debug
104   c. when breakpoint is hit, type continue. You should see output
105"Before update..."
106   d. change "Before update" to  "After update"
107   e. redefine,  and set line breakpoint (see step a)
108   f. type continue. You should see output "After update"
109   g. change "After update" to "abcde"
110   h. redefine, and set line breakpoint (see step a)
111   i.  type continue. The output is shown as "After update"
112
113   j. to see "abcde" output,  users will have to pop the stack, and
114re-execute method start().
115    ************/
116EOF
117}
118
119# This is called to feed cmds to jdb.
120dojdbCmds()
121{
122    setBkpts @1
123    runToBkpt @1
124    contToBkpt
125    redefineClass @1
126    setBkpts @1
127    contToBkpt
128    redefineClass @2
129    cmd allowExit cont
130}
131
132
133mysetup()
134{
135    if [ -z "$TESTSRC" ] ; then
136        TESTSRC=.
137    fi
138
139    for ii in . $TESTSRC $TESTSRC/.. ; do
140        if [ -r "$ii/ShellScaffold.sh" ] ; then
141            . $ii/ShellScaffold.sh 
142            break
143        fi
144    done
145}
146
147# You could replace this next line with the contents
148# of ShellScaffold.sh and this script will run just the same.
149mysetup
150
151runit
152debuggeeFailIfPresent "Internal exception:"
153debuggeeFailIfNotPresent "abcde"
154pass
155