1 #
   2 # Copyright (c) 2013, 2015, 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 # @modules java.instrument
  32 # @run shell MakeJAR3.sh RedefineSubclassWithTwoInterfacesAgent 'Can-Redefine-Classes: true'
  33 # @run build RedefineSubclassWithTwoInterfacesApp
  34 # @run shell RedefineSubclassWithTwoInterfaces.sh
  35 #
  36 
  37 if [ "${TESTJAVA}" = "" ]
  38 then
  39   echo "TESTJAVA not set.  Test cannot execute.  Failed."
  40   exit 1
  41 fi
  42 
  43 if [ "${COMPILEJAVA}" = "" ]
  44 then
  45   COMPILEJAVA="${TESTJAVA}"
  46 fi
  47 echo "COMPILEJAVA=${COMPILEJAVA}"
  48 
  49 if [ "${TESTSRC}" = "" ]
  50 then
  51   echo "TESTSRC not set.  Test cannot execute.  Failed."
  52   exit 1
  53 fi
  54 
  55 if [ "${TESTCLASSES}" = "" ]
  56 then
  57   echo "TESTCLASSES not set.  Test cannot execute.  Failed."
  58   exit 1
  59 fi
  60 
  61 JAVAC="${COMPILEJAVA}"/bin/javac
  62 JAVA="${TESTJAVA}"/bin/java
  63 
  64 echo "INFO: building the replacement classes."
  65 
  66 cp "${TESTSRC}"/RedefineSubclassWithTwoInterfacesTarget_1.java \
  67     RedefineSubclassWithTwoInterfacesTarget.java
  68 cp "${TESTSRC}"/RedefineSubclassWithTwoInterfacesImpl_1.java \
  69     RedefineSubclassWithTwoInterfacesImpl.java
  70 "${JAVAC}" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
  71     -cp "${TESTCLASSES}" -d . \
  72     RedefineSubclassWithTwoInterfacesTarget.java \
  73     RedefineSubclassWithTwoInterfacesImpl.java 
  74 status="$?"
  75 if [ "$status" != 0 ]; then
  76     echo "FAIL: compile of *_1.java files failed."
  77     exit "$status"
  78 fi
  79 
  80 mv RedefineSubclassWithTwoInterfacesTarget.java \
  81     RedefineSubclassWithTwoInterfacesTarget_1.java
  82 mv RedefineSubclassWithTwoInterfacesTarget.class \
  83     RedefineSubclassWithTwoInterfacesTarget_1.class
  84 mv RedefineSubclassWithTwoInterfacesImpl.java \
  85     RedefineSubclassWithTwoInterfacesImpl_1.java
  86 mv RedefineSubclassWithTwoInterfacesImpl.class \
  87     RedefineSubclassWithTwoInterfacesImpl_1.class
  88 
  89 echo "INFO: launching RedefineSubclassWithTwoInterfacesApp"
  90 
  91 # TraceRedefineClasses options:
  92 #
  93 #    0x00000001 |          1 - name each target class before loading, after
  94 #                              loading and after redefinition is completed
  95 #    0x00000002 |          2 - print info if parsing, linking or
  96 #                              verification throws an exception
  97 #    0x00000004 |          4 - print timer info for the VM operation
  98 #    0x00001000 |       4096 - detect calls to obsolete methods
  99 #    0x00002000 |       8192 - fail a guarantee() in addition to detection
 100 #    0x00004000 |      16384 - detect old/obsolete methods in metadata
 101 #    0x00100000 |    1048576 - impl details: vtable updates
 102 #    0x00200000 |    2097152 - impl details: itable updates
 103 #
 104 #    1+2+4+4096+8192+16384+1048576+2097152 == 3174407
 105 
 106 "${JAVA}" ${TESTVMOPTS} \
 107     -XX:TraceRedefineClasses=3174407 \
 108     -javaagent:RedefineSubclassWithTwoInterfacesAgent.jar \
 109     -classpath "${TESTCLASSES}" \
 110     RedefineSubclassWithTwoInterfacesApp > output.log 2>&1
 111 status="$?"
 112 
 113 echo "INFO: <begin output.log>"
 114 cat output.log
 115 echo "INFO: <end output.log>"
 116 
 117 if [ "$status" != 0 ]; then
 118     echo "FAIL: RedefineSubclassWithTwoInterfacesApp failed."
 119     exit "$status"
 120 fi
 121 
 122 # When this bug manifests, RedefineClasses() will fail to update
 123 # one of the itable entries to refer to the new method. The log
 124 # will include the following line when the bug occurs:
 125 #
 126 #     guarantee(false) failed: OLD and/or OBSOLETE method(s) found
 127 #
 128 # If this guarantee happens, the test should fail in the status
 129 # check above, but just in case it doesn't, we check for "guarantee".
 130 #
 131 
 132 FAIL_MESG="guarantee"
 133 grep "$FAIL_MESG" output.log
 134 status=$?
 135 if [ "$status" = 0 ]; then
 136     echo "FAIL: found '$FAIL_MESG' in the test output."
 137     result=1
 138 else
 139     echo "INFO: did NOT find '$FAIL_MESG' in the test output."
 140     # be optimistic here
 141     result=0
 142 fi
 143 
 144 PASS1_MESG="before any redefines"
 145 cnt=`grep "$PASS1_MESG" output.log | grep 'version-0' | wc -l`
 146 # no quotes around $cnt so any whitespace from 'wc -l' is ignored
 147 if [ $cnt = 2 ]; then
 148     echo "INFO: found 2 version-0 '$PASS1_MESG' mesgs."
 149 else
 150     echo "FAIL: did NOT find 2 version-0 '$PASS1_MESG' mesgs."
 151     echo "INFO: cnt='$cnt'"
 152     echo "INFO: grep '$PASS1_MESG' output:"
 153     grep "$PASS1_MESG" output.log
 154     result=1
 155 fi
 156 
 157 PASS2_MESG="after redefine"
 158 cnt=`grep "$PASS2_MESG" output.log | grep 'version-1' | wc -l`
 159 # no quotes around $cnt so any whitespace from 'wc -l' is ignored
 160 if [ $cnt = 2 ]; then
 161     echo "INFO: found 2 version-1 '$PASS2_MESG' mesgs."
 162 else
 163     echo "FAIL: did NOT find 2 version-1 '$PASS2_MESG' mesgs."
 164     echo "INFO: cnt='$cnt'"
 165     echo "INFO: grep '$PASS2_MESG' output:"
 166     grep "$PASS2_MESG" output.log
 167     result=1
 168 fi
 169 
 170 if [ "$result" = 0 ]; then
 171     echo "PASS: test passed both positive and negative output checks."
 172 fi
 173 
 174 exit $result