1 #!/bin/sh 2 3 # 4 # Copyright 2004 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22 # CA 95054 USA or visit www.sun.com if you need additional information or 23 # have any questions. 24 # 25 26 # 27 # @test 28 # @bug 4833089 4992454 29 # @summary Check for proper handling of uncaught exceptions 30 # @author Martin Buchholz 31 # 32 # @run shell UncaughtExceptions.sh 33 34 # To run this test manually, simply do ./UncaughtExceptions.sh 35 36 java="${TESTJAVA+${TESTJAVA}/bin/}java" 37 javac="${TESTJAVA+${TESTJAVA}/bin/}javac" 38 39 failed="" 40 Fail() { echo "FAIL: $1"; failed="${failed}."; } 41 42 Die() { printf "%s\n" "$*"; exit 1; } 43 44 Sys() { 45 "$@"; rc="$?"; 46 test "$rc" -eq 0 || Die "Command \"$*\" failed with exitValue $rc"; 47 } 48 49 HorizontalRule() { 50 echo "-----------------------------------------------------------------" 51 } 52 53 Bottom() { 54 test "$#" = 1 -a "$1" = "Line" || Die "Usage: Bottom Line" 55 56 HorizontalRule 57 if test -n "$failed"; then 58 count=`printf "%s" "$failed" | wc -c | tr -d ' '` 59 echo "FAIL: $count tests failed" 60 exit 1 61 else 62 echo "PASS: all tests gave expected results" 63 exit 0 64 fi 65 } 66 67 Cleanup() { Sys rm -f Seppuku* OK.class; } 68 69 set -u 70 71 checkOutput() { 72 name="$1" expected="$2" got="$3" 73 printf "$name:\n"; cat "$got" 74 if test -z "$expected"; then 75 test "`cat $got`" != "" && \ 76 Fail "Unexpected $name: `cat $got`" 77 else 78 grep "$expected" "$got" >/dev/null || \ 79 Fail "Expected \"$expected\", got `cat $got`" 80 fi 81 } 82 83 CheckCommandResults() { 84 expectedRC="$1" expectedOut="$2" expectedErr="$3"; shift 3 85 saveFailed="${failed}" 86 "$@" >TmpTest.Out 2>TmpTest.Err; rc="$?"; 87 printf "==> %s (rc=%d)\n" "$*" "$rc" 88 checkOutput "stdout" "$expectedOut" "TmpTest.Out" 89 checkOutput "stderr" "$expectedErr" "TmpTest.Err" 90 test "${saveFailed}" = "${failed}" && \ 91 echo "PASS: command completed as expected" 92 Sys rm -f TmpTest.Out TmpTest.Err 93 } 94 95 Run() { 96 expectedRC="$1" expectedOut="$2" expectedErr="$3" mainBody="$4" 97 cat > Seppuku.java <<EOJAVA 98 import static java.lang.Thread.*; 99 import static java.lang.System.*; 100 101 class OK implements UncaughtExceptionHandler { 102 public void uncaughtException(Thread t, Throwable e) { 103 out.println("OK"); 104 } 105 } 106 107 class NeverInvoked implements UncaughtExceptionHandler { 108 public void uncaughtException(Thread t, Throwable e) { 109 err.println("Test failure: This handler should never be invoked!"); 110 } 111 } 112 113 public class Seppuku extends Thread implements Runnable { 114 public static void seppuku() { throw new RuntimeException("Seppuku!"); } 115 116 public void run() { seppuku(); } 117 118 public static void main(String[] args) throws Exception { 119 $mainBody 120 } 121 } 122 EOJAVA 123 124 Sys "$javac" "-source" "1.5" "Seppuku.java" 125 CheckCommandResults "$expectedRC" "$expectedOut" "$expectedErr" \ 126 "$java" "Seppuku" 127 Cleanup 128 } 129 130 #---------------------------------------------------------------- 131 # A thread is never alive after you've join()ed it. 132 #---------------------------------------------------------------- 133 Run 0 "OK" "Exception in thread \"Thread-0\".*Seppuku" " 134 Thread t = new Seppuku(); 135 t.start(); t.join(); 136 if (! t.isAlive()) 137 out.println(\"OK\");" 138 139 #---------------------------------------------------------------- 140 # Even the main thread is mortal - here it terminates "abruptly" 141 #---------------------------------------------------------------- 142 Run 1 "OK" "Exception in thread \"main\".*Seppuku" " 143 final Thread mainThread = currentThread(); 144 new Thread() { public void run() { 145 try { mainThread.join(); } 146 catch (InterruptedException e) {} 147 if (! mainThread.isAlive()) 148 out.println(\"OK\"); 149 }}.start(); 150 seppuku();" 151 152 #---------------------------------------------------------------- 153 # Even the main thread is mortal - here it terminates normally. 154 #---------------------------------------------------------------- 155 Run 0 "OK" "" " 156 final Thread mainThread = currentThread(); 157 new Thread() { public void run() { 158 try { mainThread.join(); } 159 catch (InterruptedException e) {} 160 if (! mainThread.isAlive()) 161 out.println(\"OK\"); 162 }}.start();" 163 164 #---------------------------------------------------------------- 165 # Check uncaught exception handler mechanism on the main thread. 166 # Check that thread-level handler overrides global default handler. 167 #---------------------------------------------------------------- 168 Run 1 "OK" "" " 169 currentThread().setUncaughtExceptionHandler(new OK()); 170 setDefaultUncaughtExceptionHandler(new NeverInvoked()); 171 seppuku();" 172 173 Run 1 "OK" "" " 174 setDefaultUncaughtExceptionHandler(new OK()); 175 seppuku();" 176 177 #---------------------------------------------------------------- 178 # Check uncaught exception handler mechanism on non-main threads. 179 #---------------------------------------------------------------- 180 Run 0 "OK" "" " 181 Thread t = new Seppuku(); 182 t.setUncaughtExceptionHandler(new OK()); 183 t.start();" 184 185 Run 0 "OK" "" " 186 setDefaultUncaughtExceptionHandler(new OK()); 187 new Seppuku().start();" 188 189 #---------------------------------------------------------------- 190 # Test ThreadGroup based uncaught exception handler mechanism. 191 # Since the handler for the main thread group cannot be changed, 192 # there are no tests for the main thread here. 193 #---------------------------------------------------------------- 194 Run 0 "OK" "" " 195 setDefaultUncaughtExceptionHandler(new NeverInvoked()); 196 new Thread( 197 new ThreadGroup(\"OK\") { 198 public void uncaughtException(Thread t, Throwable e) { 199 out.println(\"OK\");}}, 200 new Seppuku() 201 ).start();" 202 203 Cleanup 204 205 Bottom Line