import java.util.*; import java.util.regex.*; import java.lang.reflect.*; import java.text.*; import java.io.*; import java.nio.*; import java.nio.charset.*; import java.security.*; class G19115 { // The documentation says System.nanoTime() does not return actual time, but a relative // time to some fixed origin. private static int n = (int) ((System.nanoTime() % 40) + 40) % 40; @SuppressWarnings("deprecation") public static void main(String args[]) { /** * If the code is stated to be a bug, then it is only guaranteed to throw Exception on * Oracle's JVM (or OpenJDK). Even if you are running Oracle's JVM, there is no * guarantee it will throw Exception in all future releases future either (since bugs * might be fixed, classes might be reimplemented, and an asteroid might hit the earth, * in order from the least likely to most likely). */ System.out.println(n); switch (n) { case 0: // Bug JDK-7080302 // https://bugs.openjdk.java.net/browse/JDK-7080302 // PatternSyntaxException System.out.println(Pattern.compile("a(\u0041\u0301\u0328)", Pattern.CANON_EQ)); System.out.println(Pattern.compile("??", Pattern.CANON_EQ)); // Leave this boring pattern here just in case System.out.println(Pattern.compile("[[]]")); break; case 1: // Bug JDK-6984178 // https://bugs.openjdk.java.net/browse/JDK-6984178 // StringIndexOutOfBoundsException System.out.println(new String(new char[42]).matches("(?:(?=(\\2|^))(?=(\\2\\3|^.))(?=(\\1))\\2)+.")); // Leave this boring code here just in case System.out.println("".charAt(1)); break; case 2: // IllegalArgumentException // Should throw IllegalArgumentException... by documentation, but does not! // Bug report submitted System.out.println(Pattern.compile("pattern", 0xFFFFFFFF)); // One that actually throws IllegalArgumentException System.out.println(new SimpleDateFormat("Nothing to see here")); break; case 3: // Bug JDK-6337993 (and many others...) // https://bugs.openjdk.java.net/browse/JDK-6337993 // StackOverflowError StringBuffer buf = new StringBuffer(2000); for (int i = 0; i < 1000; i++) { buf.append("xy"); } System.out.println(buf.toString().matches("(x|y)*")); // Leave this boring code here just in case main(args); break; case 4: // NumberFormatException String in4 = "123\r\n"; Matcher m4 = Pattern.compile("^\\d+$").matcher(in4); if (m4.find()) { System.out.println(Integer.parseInt(in4)); } else { System.out.println("Bad input"); } // NotABug(TM) StatusByDesign(TM) // $ by default can match just before final trailing newline character in Java // This is why matches() should be used, or we can call m.group() to get the string matched break; case 5: // IllegalStateException String in5 = "123 345 678 901"; Matcher m5 = Pattern.compile("\\d+").matcher(in5); System.out.println(m5.group(0)); // The Matcher doesn't start matching the string by itself... break; case 6: // ArrayIndexOutOfBoundsException // Who is the culprit? String[] in6 = { "Nice weather today. Perfect for a stroll along the beach.", " Mmmy keeyboaardd iisss bbrokkkkeeen ..", "", "\t\t\t \n\n"}; for (String s: in6) { System.out.println("First token: " + s.split("\\s+")[0]); } // Culprit is "\t\t\t \n\n" // String.split() returns array length 1 with empty string if input is empty string // array length 0 if input is non-empty and all characters match the regex break; case 7: // ConcurrentModificationException List<Integer> l7 = testRandom(42); Integer prev = null; // Remove duplicate numbers from the list for (Integer i7: l7) { if (prev == null) { prev = i7; } else { if (i7.equals(prev)) { l7.remove(i7); } } } System.out.println(l7); // This is one of the typical mistakes that Java newbies run into break; case 8: // ArithmeticException // Integer division by 0 seems to be the only way to trigger this exception? System.out.println(0/0); break; case 9: // ExceptionInInitializerError // Thrown when there is an Exception raised during initialization of the class // What Exception will be thrown here? Static s9 = null; System.out.println(s9.k); // A bit less interesting Static ss9 = new Static(); // ---- // A class is only initialized when any of its method/field is // used for the first time (directly or indirectly) // Below code won't throw Exception, since we never access its fields or methods // Static s; // OR // Static s = null; break; case 10: // BufferOverflowException short s10 = 20000; ShortBuffer b10 = ShortBuffer.allocate(0).put(s10); // Boring stuff... break; case 11: // BufferUnderflowException ShortBuffer.allocate(0).get(); // Another boring stuff... break; case 12: // InvalidMarkException ShortBuffer.allocate(0).reset(); // Boring stuff again... // reset() cannot be called if mark() is not called before break; case 13: // IndexOutOfBoundsException System.out.println("I lost $m dollars".replaceAll("[$]m\\b", "$2")); // $ needs to be escaped in replacement string, since it is special break; case 14: // ClassCastException Class c14 = Character.class; for (Field f: c14.getFields()) { System.out.println(f); try { int o = (int) f.get(c14); // If the result is of primitive type, it is boxed before returning // Check implementation of sun.reflect.UnsafeStaticIntegerFieldAccessorImpl System.out.println(o); } catch (IllegalAccessException e) { e.printStackTrace(); } } break; case 15: // NoSuchElementException List<Integer> l15 = new ArrayList<Integer>(); Iterator i = l15.iterator(); System.out.println(i.next()); // Another boring one... break; case 16: // ArrayStoreException Object x[] = new String[3]; x[0] = new Integer(0); // Straight from the documentation // I don't even know that this exists... break; case 17: // IllegalThreadStateException Thread t17 = new Thread(); t17.start(); t17.setDaemon(true); // setDaemon can only be called when the thread has not started or has died break; case 18: // EmptyStackException Stack<Integer> s18 = new Stack<Integer>(); s18.addAll(testRandom(43)); while (s18.pop() != null); // Originally ThreadDeath, which works when running from Dr. Java but not when // running on cmd line. Seems that Dr. Java provides its own version of // Thread.UncaughtExceptionHandler that prints out ThreadDeath. // Please make do with this boring Exception break; case 19: // NegativeArraySizeException Array.newInstance(Integer.TYPE, -1); // Do they have to create such a specific Exception? break; case 20: // OutOfMemoryError Array.newInstance(Integer.TYPE, 1000, 1000, 1000, 1000); break; case 21: // UnsupportedCharsetException // This is implementation-dependent Charset cs21 = Charset.forName("UCS-2"); CharsetEncoder ce21 = cs21.newEncoder(); break; case 22: // IllegalCharsetNameException boolean isSupported; isSupported = Charset.isSupported("o_O"); isSupported = Charset.isSupported("+_+"); Charset cs22 = Charset.forName("MerryChristmas!Hohoho!"); // This is getting stupid... break; case 23: // NoClassDefFoundError File f = new File("ToBeRemoved.class"); f.delete(); ToBeRemoved o23 = new ToBeRemoved(); // This shows that class is loaded on demand break; case 24: // InputMismatchException Scanner sc = new Scanner("2987654321"); sc.nextInt(); // Out of range break; case 25: // Formatter class has many RuntimeException defined // DuplicateFormatFlagsException System.out.printf("%0000000000000000000000000000000000000000000000000005%d\n", 42); break; case 26: // FormatFlagsConversionMismatchException System.out.printf("%,d\n", Integer.MAX_VALUE); System.out.printf("%,x\n", Integer.MAX_VALUE); // Thousand separator is only applicable to base 10 System.out.printf("%(5.4f\n", Math.PI); System.out.printf("%(5.4f\n", -Math.PI); System.out.printf("%(5.4a\n", -Math.PI); // '(' flag is used to surround negative value with "( )" instead of prefixing with '-' // '(' can't be used with conversion 'a' break; case 27: // IllegalFormatCodePointException System.out.printf("%c", Character.MAX_CODE_POINT + 1); // Larger than current Unicode maximum code point (0x10FFFF) break; case 28: // IllegalFormatConversionException String i28 = "0"; System.out.printf("%d", i28); // A boring example break; case 29: // IllegalFormatFlagsException System.out.printf("% d\n", Integer.MAX_VALUE); System.out.printf("% d\n", Integer.MIN_VALUE); System.out.printf("%+d\n", Integer.MAX_VALUE); System.out.printf("%+d\n", Integer.MIN_VALUE); System.out.printf("% +d\n", Integer.MIN_VALUE); // Use either ' ' or '+ ' flag, not both, since they are mutually exclusive break; case 30: // IllegalFormatPrecisionException System.out.printf("%5.4f\n", Math.PI); System.out.printf("%5.4a\n", Math.PI); System.out.printf("%5.4x\n", Math.PI); // Precision does not apply to 'x', which is integer hexadecimal conversion // To print a floating point number in hexadecimal, use conversion 'a' break; case 31: // IllegalFormatWidthException System.out.printf("%3n"); // For conversion n, width is not supported break; case 32: // MissingFormatArgumentException System.out.printf("%s\n%<s", "Pointing to previous argument\n"); System.out.printf("%<s", "Pointing to previous argument"); // No previous argument break; case 33: // MissingFormatWidthException System.out.printf("%5d %<d\n", 42); // Pad left System.out.printf("%-5d %<d\n", 42); // Pad right System.out.printf("%-d\n", 42); // Missing width break; case 34: // UnknownFormatConversionException System.out.printf("%q", "Shouldn't work"); // No format conversion %q // UnknownFormatFlagsException cannot be thrown by Formatter class in // Oracle's implementation, since the flags have been checked in the regex // used to recognize the format string break; case 35: // IllformedLocaleException System.out.printf(new Locale("ja"), "%tA %<tB %<tD %<tT %<tZ %<tY\n", new Date()); System.out.printf(new Locale.Builder().setLanguage("ja").setScript("JA").setRegion("JA").build(), "%tA %<tB %<tD %<tT %<tZ %<tf\n", new Date()); // Thrown by Locale.Builder.setScript() break; case 36: // NullPointerException Pattern p36 = Pattern.compile("a(b)?c"); Matcher m36 = p36.matcher("ac"); if (m36.find()) { for (int i36 = 0; i36 <= m36.groupCount(); i36++) { // Use Matcher#end(num) - Matcher#start(num) for length instead System.out.printf("%3d [%d]: %s\n", i36, m36.group(i36).length(), m36.group(i36)); } } break; case 37: // AccessControlException System.setSecurityManager(new SecurityManager()); System.setSecurityManager(new SecurityManager()); break; case 38: // SecurityException // Implementation-dependent Class ϲlass = Class.class; Constructor[] constructors = ϲlass.getDeclaredConstructors(); for (Constructor constructor: constructors) { constructor.setAccessible(true); try { Class Сlass = (Class) constructor.newInstance(); } catch (Throwable e) { System.out.println(e.getMessage()); } // The code should reach here without any Exception... right? } // It is obvious once you run the code // There are very few ways to get SecurityException (and not one of its subclasses) // This is one of the ways break; case 39: // UnknownFormatFlagsException // Implementation-dependent try { System.out.printf("%=d", "20"); } catch (Exception e) { // Just to show the original Exception System.out.println(e.getClass()); } Class classFormatter = Formatter.class; Field[] fs39 = classFormatter.getDeclaredFields(); boolean patternFound = false; for (Field f39: fs39) { if (Pattern.class.isAssignableFrom(f39.getType())) { f39.setAccessible(true); // Add = to the list of flags try { f39.set(classFormatter, Pattern.compile("%(\\d+\\$)?([-#+ 0,(\\<=]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])")); } catch (IllegalAccessException e) { System.out.println(e.getMessage()); } patternFound = true; } } if (patternFound) { System.out.printf("%=d", "20"); } // As discussed before UnknownFormatFlagsException cannot be thrown by Oracle's // current implementation. The reflection code above add = to the list of flags // to be parsed to enable the path to the UnknownFormatFlagsException. break; } } /* * This method is used to check whether all numbers under d are generated when we call * new Object().hashCode() % d. * * However, hashCode() is later replaced by System.nanoTime(), since it got stuck at * some values when the JVM is stopped and restarted every time (running on command line). */ private static List<Integer> testRandom(int d) { List<Integer> k = new ArrayList<Integer>(); for (int i = 0; i < 250; i++) { k.add(new Object().hashCode() % d); } Collections.sort(k); System.out.println(k); return k; } } class ToBeRemoved {}; class Static { static public int k = 0; static { System.out.println(0/0); } }
import java.util.*; import java.util.regex.*; import java.lang.reflect.*; import java.text.*; import java.io.*; import java.nio.*; import java.nio.charset.*; import java.security.*; class G19115 { // The documentation says System.nanoTime() does not return actual time, but a relative // time to some fixed origin. private static int n = (int) ((System.nanoTime() % 40) + 40) % 40; @SuppressWarnings("deprecation") public static void main(String args[]) { /** * If the code is stated to be a bug, then it is only guaranteed to throw Exception on * Oracle's JVM (or OpenJDK). Even if you are running Oracle's JVM, there is no * guarantee it will throw Exception in all future releases future either (since bugs * might be fixed, classes might be reimplemented, and an asteroid might hit the earth, * in order from the least likely to most likely). */ System.out.println(n); switch (n) { case 0: // Bug JDK-7080302 // https://bugs.openjdk.java.net/browse/JDK-7080302 // PatternSyntaxException System.out.println(Pattern.compile("a(\u0041\u0301\u0328)", Pattern.CANON_EQ)); System.out.println(Pattern.compile("??", Pattern.CANON_EQ)); // Leave this boring pattern here just in case System.out.println(Pattern.compile("[[]]")); break; case 1: // Bug JDK-6984178 // https://bugs.openjdk.java.net/browse/JDK-6984178 // StringIndexOutOfBoundsException System.out.println(new String(new char[42]).matches("(?:(?=(\\2|^))(?=(\\2\\3|^.))(?=(\\1))\\2)+.")); // Leave this boring code here just in case System.out.println("".charAt(1)); break; case 2: // IllegalArgumentException // Should throw IllegalArgumentException... by documentation, but does not! // Bug report submitted System.out.println(Pattern.compile("pattern", 0xFFFFFFFF)); // One that actually throws IllegalArgumentException System.out.println(new SimpleDateFormat("Nothing to see here")); break; case 3: // Bug JDK-6337993 (and many others...) // https://bugs.openjdk.java.net/browse/JDK-6337993 // StackOverflowError StringBuffer buf = new StringBuffer(2000); for (int i = 0; i < 1000; i++) { buf.append("xy"); } System.out.println(buf.toString().matches("(x|y)*")); // Leave this boring code here just in case main(args); break; case 4: // NumberFormatException String in4 = "123\r\n"; Matcher m4 = Pattern.compile("^\\d+$").matcher(in4); if (m4.find()) { System.out.println(Integer.parseInt(in4)); } else { System.out.println("Bad input"); } // NotABug(TM) StatusByDesign(TM) // $ by default can match just before final trailing newline character in Java // This is why matches() should be used, or we can call m.group() to get the string matched break; case 5: // IllegalStateException String in5 = "123 345 678 901"; Matcher m5 = Pattern.compile("\\d+").matcher(in5); System.out.println(m5.group(0)); // The Matcher doesn't start matching the string by itself... break; case 6: // ArrayIndexOutOfBoundsException // Who is the culprit? String[] in6 = { "Nice weather today. Perfect for a stroll along the beach.", " Mmmy keeyboaardd iisss bbrokkkkeeen ..", "", "\t\t\t \n\n"}; for (String s: in6) { System.out.println("First token: " + s.split("\\s+")[0]); } // Culprit is "\t\t\t \n\n" // String.split() returns array length 1 with empty string if input is empty string // array length 0 if input is non-empty and all characters match the regex break; case 7: // ConcurrentModificationException List<Integer> l7 = testRandom(42); Integer prev = null; // Remove duplicate numbers from the list for (Integer i7: l7) { if (prev == null) { prev = i7; } else { if (i7.equals(prev)) { l7.remove(i7); } } } System.out.println(l7); // This is one of the typical mistakes that Java newbies run into break; case 8: // ArithmeticException // Integer division by 0 seems to be the only way to trigger this exception? System.out.println(0/0); break; case 9: // ExceptionInInitializerError // Thrown when there is an Exception raised during initialization of the class // What Exception will be thrown here? Static s9 = null; System.out.println(s9.k); // A bit less interesting Static ss9 = new Static(); // ---- // A class is only initialized when any of its method/field is // used for the first time (directly or indirectly) // Below code won't throw Exception, since we never access its fields or methods // Static s; // OR // Static s = null; break; case 10: // BufferOverflowException short s10 = 20000; ShortBuffer b10 = ShortBuffer.allocate(0).put(s10); // Boring stuff... break; case 11: // BufferUnderflowException ShortBuffer.allocate(0).get(); // Another boring stuff... break; case 12: // InvalidMarkException ShortBuffer.allocate(0).reset(); // Boring stuff again... // reset() cannot be called if mark() is not called before break; case 13: // IndexOutOfBoundsException System.out.println("I lost $m dollars".replaceAll("[$]m\\b", "$2")); // $ needs to be escaped in replacement string, since it is special break; case 14: // ClassCastException Class c14 = Character.class; for (Field f: c14.getFields()) { System.out.println(f); try { int o = (int) f.get(c14); // If the result is of primitive type, it is boxed before returning // Check implementation of sun.reflect.UnsafeStaticIntegerFieldAccessorImpl System.out.println(o); } catch (IllegalAccessException e) { e.printStackTrace(); } } break; case 15: // NoSuchElementException List<Integer> l15 = new ArrayList<Integer>(); Iterator i = l15.iterator(); System.out.println(i.next()); // Another boring one... break; case 16: // ArrayStoreException Object x[] = new String[3]; x[0] = new Integer(0); // Straight from the documentation // I don't even know that this exists... break; case 17: // IllegalThreadStateException Thread t17 = new Thread(); t17.start(); t17.setDaemon(true); // setDaemon can only be called when the thread has not started or has died break; case 18: // EmptyStackException Stack<Integer> s18 = new Stack<Integer>(); s18.addAll(testRandom(43)); while (s18.pop() != null); // Originally ThreadDeath, which works when running from Dr. Java but not when // running on cmd line. Seems that Dr. Java provides its own version of // Thread.UncaughtExceptionHandler that prints out ThreadDeath. // Please make do with this boring Exception break; case 19: // NegativeArraySizeException Array.newInstance(Integer.TYPE, -1); // Do they have to create such a specific Exception? break; case 20: // OutOfMemoryError Array.newInstance(Integer.TYPE, 1000, 1000, 1000, 1000); break; case 21: // UnsupportedCharsetException // This is implementation-dependent Charset cs21 = Charset.forName("UCS-2"); CharsetEncoder ce21 = cs21.newEncoder(); break; case 22: // IllegalCharsetNameException boolean isSupported; isSupported = Charset.isSupported("o_O"); isSupported = Charset.isSupported("+_+"); Charset cs22 = Charset.forName("MerryChristmas!Hohoho!"); // This is getting stupid... break; case 23: // NoClassDefFoundError File f = new File("ToBeRemoved.class"); f.delete(); ToBeRemoved o23 = new ToBeRemoved(); // This shows that class is loaded on demand break; case 24: // InputMismatchException Scanner sc = new Scanner("2987654321"); sc.nextInt(); // Out of range break; case 25: // Formatter class has many RuntimeException defined // DuplicateFormatFlagsException System.out.printf("%0000000000000000000000000000000000000000000000000005%d\n", 42); break; case 26: // FormatFlagsConversionMismatchException System.out.printf("%,d\n", Integer.MAX_VALUE); System.out.printf("%,x\n", Integer.MAX_VALUE); // Thousand separator is only applicable to base 10 System.out.printf("%(5.4f\n", Math.PI); System.out.printf("%(5.4f\n", -Math.PI); System.out.printf("%(5.4a\n", -Math.PI); // '(' flag is used to surround negative value with "( )" instead of prefixing with '-' // '(' can't be used with conversion 'a' break; case 27: // IllegalFormatCodePointException System.out.printf("%c", Character.MAX_CODE_POINT + 1); // Larger than current Unicode maximum code point (0x10FFFF) break; case 28: // IllegalFormatConversionException String i28 = "0"; System.out.printf("%d", i28); // A boring example break; case 29: // IllegalFormatFlagsException System.out.printf("% d\n", Integer.MAX_VALUE); System.out.printf("% d\n", Integer.MIN_VALUE); System.out.printf("%+d\n", Integer.MAX_VALUE); System.out.printf("%+d\n", Integer.MIN_VALUE); System.out.printf("% +d\n", Integer.MIN_VALUE); // Use either ' ' or '+ ' flag, not both, since they are mutually exclusive break; case 30: // IllegalFormatPrecisionException System.out.printf("%5.4f\n", Math.PI); System.out.printf("%5.4a\n", Math.PI); System.out.printf("%5.4x\n", Math.PI); // Precision does not apply to 'x', which is integer hexadecimal conversion // To print a floating point number in hexadecimal, use conversion 'a' break; case 31: // IllegalFormatWidthException System.out.printf("%3n"); // For conversion n, width is not supported break; case 32: // MissingFormatArgumentException System.out.printf("%s\n%<s", "Pointing to previous argument\n"); System.out.printf("%<s", "Pointing to previous argument"); // No previous argument break; case 33: // MissingFormatWidthException System.out.printf("%5d %<d\n", 42); // Pad left System.out.printf("%-5d %<d\n", 42); // Pad right System.out.printf("%-d\n", 42); // Missing width break; case 34: // UnknownFormatConversionException System.out.printf("%q", "Shouldn't work"); // No format conversion %q // UnknownFormatFlagsException cannot be thrown by Formatter class in // Oracle's implementation, since the flags have been checked in the regex // used to recognize the format string break; case 35: // IllformedLocaleException System.out.printf(new Locale("ja"), "%tA %<tB %<tD %<tT %<tZ %<tY\n", new Date()); System.out.printf(new Locale.Builder().setLanguage("ja").setScript("JA").setRegion("JA").build(), "%tA %<tB %<tD %<tT %<tZ %<tf\n", new Date()); // Thrown by Locale.Builder.setScript() break; case 36: // NullPointerException Pattern p36 = Pattern.compile("a(b)?c"); Matcher m36 = p36.matcher("ac"); if (m36.find()) { for (int i36 = 0; i36 <= m36.groupCount(); i36++) { // Use Matcher#end(num) - Matcher#start(num) for length instead System.out.printf("%3d [%d]: %s\n", i36, m36.group(i36).length(), m36.group(i36)); } } break; case 37: // AccessControlException System.setSecurityManager(new SecurityManager()); System.setSecurityManager(new SecurityManager()); break; case 38: // SecurityException // Implementation-dependent Class ϲlass = Class.class; Constructor[] constructors = ϲlass.getDeclaredConstructors(); for (Constructor constructor: constructors) { constructor.setAccessible(true); try { Class Сlass = (Class) constructor.newInstance(); } catch (Throwable e) { System.out.println(e.getMessage()); } // The code should reach here without any Exception... right? } // It is obvious once you run the code // There are very few ways to get SecurityException (and not one of its subclasses) // This is one of the ways break; case 39: // UnknownFormatFlagsException // Implementation-dependent try { System.out.printf("%=d", "20"); } catch (Exception e) { // Just to show the original Exception System.out.println(e.getClass()); } Class classFormatter = Formatter.class; Field[] fs39 = classFormatter.getDeclaredFields(); boolean patternFound = false; for (Field f39: fs39) { if (Pattern.class.isAssignableFrom(f39.getType())) { f39.setAccessible(true); // Add = to the list of flags try { f39.set(classFormatter, Pattern.compile("%(\\d+\\$)?([-#+ 0,(\\<=]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])")); } catch (IllegalAccessException e) { System.out.println(e.getMessage()); } patternFound = true; } } if (patternFound) { System.out.printf("%=d", "20"); } // As discussed before UnknownFormatFlagsException cannot be thrown by Oracle's // current implementation. The reflection code above add = to the list of flags // to be parsed to enable the path to the UnknownFormatFlagsException. break; } } /* * This method is used to check whether all numbers under d are generated when we call * new Object().hashCode() % d. * * However, hashCode() is later replaced by System.nanoTime(), since it got stuck at * some values when the JVM is stopped and restarted every time (running on command line). */ private static List<Integer> testRandom(int d) { List<Integer> k = new ArrayList<Integer>(); for (int i = 0; i < 250; i++) { k.add(new Object().hashCode() % d); } Collections.sort(k); System.out.println(k); return k; } } class ToBeRemoved {}; class Static { static public int k = 0; static { System.out.println(0/0); } }