1 #
   2 # Copyright (c) 2013, 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.
   8 #
   9 # This code is distributed in the hope that it will be useful, but WITHOUT
  10 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12 # version 2 for more details (a copy is included in the LICENSE file that
  13 # accompanied this code).
  14 #
  15 # You should have received a copy of the GNU General Public License version
  16 # 2 along with this work; if not, write to the Free Software Foundation,
  17 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18 #
  19 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20 # or visit www.oracle.com if you need additional information or have any
  21 # questions.
  22 #
  23 
  24 # @test
  25 # @bug 7182152
  26 # @bug 8007935
  27 # @summary Redefine a subclass that implements two interfaces and
  28 #   verify that the right methods are called.
  29 # @author Daniel D. Daugherty
  30 #
  31 # @run shell MakeJAR3.sh RedefineSubclassWithTwoInterfacesAgent 'Can-Redefine-Classes: true'
  32 # @run build RedefineSubclassWithTwoInterfacesApp
  33 # @run shell RedefineSubclassWithTwoInterfaces.sh
  34 #
  35 
  36 if [ "${TESTJAVA}" = "" ]
  37 then
  38   echo "TESTJAVA not set.  Test cannot execute.  Failed."
  39   exit 1
  40 fi
  41 
  42 if [ "${COMPILEJAVA}" = "" ]
  43 then
  44   COMPILEJAVA="${TESTJAVA}"
  45 fi
  46 echo "COMPILEJAVA=${COMPILEJAVA}"
  47 
  48 if [ "${TESTSRC}" = "" ]
  49 then
  50   echo "TESTSRC not set.  Test cannot execute.  Failed."
  51   exit 1
  52 fi
  53 
  54 if [ "${TESTCLASSES}" = "" ]
  55 then
  56   echo "TESTCLASSES not set.  Test cannot execute.  Failed."
  57   exit 1
  58 fi
  59 
  60 JAVAC="${COMPILEJAVA}"/bin/javac
  61 JAVA="${TESTJAVA}"/bin/java
  62 
  63 echo "INFO: building the replacement classes."
  64 
  65 cp "${TESTSRC}"/RedefineSubclassWithTwoInterfacesTarget_1.java \
  66     RedefineSubclassWithTwoInterfacesTarget.java
  67 cp "${TESTSRC}"/RedefineSubclassWithTwoInterfacesImpl_1.java \
  68     RedefineSubclassWithTwoInterfacesImpl.java
  69 "${JAVAC}" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
  70     -cp "${TESTCLASSES}" -d . \
  71     RedefineSubclassWithTwoInterfacesTarget.java \
  72     RedefineSubclassWithTwoInterfacesImpl.java 
  73 status="$?"
  74 if [ "$status" != 0 ]; then
  75     echo "FAIL: compile of *_1.java files failed."
  76     exit "$status"
  77 fi
  78 
  79 mv RedefineSubclassWithTwoInterfacesTarget.java \
  80     RedefineSubclassWithTwoInterfacesTarget_1.java
  81 mv RedefineSubclassWithTwoInterfacesTarget.class \
  82     RedefineSubclassWithTwoInterfacesTarget_1.class
  83 mv RedefineSubclassWithTwoInterfacesImpl.java \
  84     RedefineSubclassWithTwoInterfacesImpl_1.java
  85 mv RedefineSubclassWithTwoInterfacesImpl.class \
  86     RedefineSubclassWithTwoInterfacesImpl_1.class
  87 
  88 echo "INFO: launching RedefineSubclassWithTwoInterfacesApp"
  89 
  90 # TraceRedefineClasses options:
  91 #
  92 #    0x00000001 |          1 - name each target class before loading, after
  93 #                              loading and after redefinition is completed
  94 #    0x00000002 |          2 - print info if parsing, linking or
  95 #                              verification throws an exception
  96 #    0x00000004 |          4 - print timer info for the VM operation
  97 #    0x00001000 |       4096 - detect calls to obsolete methods
  98 #    0x00002000 |       8192 - fail a guarantee() in addition to detection
  99 #    0x00004000 |      16384 - detect old/obsolete methods in metadata
 100 #    0x00100000 |    1048576 - impl details: vtable updates
 101 #    0x00200000 |    2097152 - impl details: itable updates
 102 #
 103 #    1+2+4+4096+8192+16384+1048576+2097152 == 3174407
 104 
 105 "${JAVA}" ${TESTVMOPTS} \
 106     -XX:TraceRedefineClasses=3174407 \
 107     -javaagent:RedefineSubclassWithTwoInterfacesAgent.jar \
 108     -classpath "${TESTCLASSES}" \
 109     RedefineSubclassWithTwoInterfacesApp > output.log 2>&1
 110 status="$?"
 111 
 112 echo "INFO: <begin output.log>"
 113 cat output.log
 114 echo "INFO: <end output.log>"
 115 
 116 if [ "$status" != 0 ]; then
 117     echo "FAIL: RedefineSubclassWithTwoInterfacesApp failed."
 118     exit "$status"
 119 fi
 120 
 121 # When this bug manifests, RedefineClasses() will fail to update
 122 # one of the itable entries to refer to the new method. The log
 123 # will include the following line when the bug occurs:
 124 #
 125 #     guarantee(false) failed: OLD and/or OBSOLETE method(s) found
 126 #
 127 # If this guarantee happens, the test should fail in the status
 128 # check above, but just in case it doesn't, we check for "guarantee".
 129 #
 130 
 131 FAIL_MESG="guarantee"
 132 grep "$FAIL_MESG" output.log
 133 status=$?
 134 if [ "$status" = 0 ]; then
 135     echo "FAIL: found '$FAIL_MESG' in the test output."
 136     result=1
 137 else
 138     echo "INFO: did NOT find '$FAIL_MESG' in the test output."
 139     # be optimistic here
 140     result=0
 141 fi
 142 
 143 PASS1_MESG="before any redefines"
 144 cnt=`grep "$PASS1_MESG" output.log | grep 'version-0' | wc -l`
 145 # no quotes around $cnt so any whitespace from 'wc -l' is ignored
 146 if [ $cnt = 2 ]; then
 147     echo "INFO: found 2 version-0 '$PASS1_MESG' mesgs."
 148 else
 149     echo "FAIL: did NOT find 2 version-0 '$PASS1_MESG' mesgs."
 150     echo "INFO: cnt='$cnt'"
 151     echo "INFO: grep '$PASS1_MESG' output:"
 152     grep "$PASS1_MESG" output.log
 153     result=1
 154 fi
 155 
 156 PASS2_MESG="after redefine"
 157 cnt=`grep "$PASS2_MESG" output.log | grep 'version-1' | wc -l`
 158 # no quotes around $cnt so any whitespace from 'wc -l' is ignored
 159 if [ $cnt = 2 ]; then
 160     echo "INFO: found 2 version-1 '$PASS2_MESG' mesgs."
 161 else
 162     echo "FAIL: did NOT find 2 version-1 '$PASS2_MESG' mesgs."
 163     echo "INFO: cnt='$cnt'"
 164     echo "INFO: grep '$PASS2_MESG' output:"
 165     grep "$PASS2_MESG" output.log
 166     result=1
 167 fi
 168 
 169 if [ "$result" = 0 ]; then
 170     echo "PASS: test passed both positive and negative output checks."
 171 fi
 172 
 173 exit $result