TwrClose.java revision 3351:d30f35629f0e
1/* 2 * Copyright (c) 2016, 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/* 25 * @test 26 * @bug 7020499 27 * @summary Verify that the close resource code works properly in all cases 28 * @library /tools/lib 29 * @modules jdk.compiler/com.sun.tools.javac.api 30 * jdk.compiler/com.sun.tools.javac.comp 31 * jdk.compiler/com.sun.tools.javac.main 32 * @build toolbox.ToolBox TwrClose 33 * @run main TwrClose 34 */ 35 36import javax.tools.JavaFileManager; 37import javax.tools.StandardLocation; 38import javax.tools.ToolProvider; 39 40import com.sun.tools.javac.comp.Lower; 41 42import toolbox.JavacTask; 43import toolbox.ToolBox; 44 45public class TwrClose { 46 47 public static void main(String... args) throws Exception { 48 for (int i = 1; i < Lower.USE_CLOSE_RESOURCE_METHOD_THRESHOLD * 2; i++) { 49 new TwrClose().compile(i); 50 } 51 } 52 53 ToolBox tb = new ToolBox(); 54 JavaFileManager fm = ToolProvider.getSystemJavaCompiler() 55 .getStandardFileManager(null, null, null); 56 57 void compile(int trysCount) throws Exception { 58 StringBuilder testInvocations = new StringBuilder(); 59 StringBuilder testMethods = new StringBuilder(); 60 61 for (int i = 0; i < trysCount; i++) { 62 testInvocations.append(TEST_INVOCATIONS_TEMPLATE.replace("#N", Integer.toString(i))); 63 testMethods.append(TEST_METHOD_TEMPLATE.replace("#N", Integer.toString(i))); 64 } 65 66 String sourceCode = FILE_TEMPLATE.replace("#TEST_INVOCATIONS", testInvocations.toString()) 67 .replace("#TEST_METHODS", testMethods.toString()); 68 69 System.err.println("analyzing:"); 70 System.err.println(sourceCode); 71 72 try (ToolBox.MemoryFileManager mfm = new ToolBox.MemoryFileManager()) { 73 new JavacTask(tb).fileManager(mfm) 74 .sources(sourceCode) 75 .run() 76 .writeAll(); 77 ClassLoader cl = new ClassLoader(TwrClose.class.getClassLoader()) { 78 @Override 79 protected Class<?> findClass(String name) throws ClassNotFoundException { 80 byte[] data = mfm.getFileBytes(StandardLocation.CLASS_OUTPUT, name); 81 if (data != null) { 82 return defineClass(name, data, 0, data.length); 83 } 84 return super.findClass(name); 85 } 86 }; 87 88 ((Runnable) cl.loadClass("Test").newInstance()).run(); 89 } 90 } 91 92 final String TEST_INVOCATIONS_TEMPLATE = 93 " test#N(false, false, Arrays.asList(\"close\"));\n" + 94 " test#N(false, true, Arrays.asList(\"close\", \"close-exception\"));\n" + 95 " test#N(true, false, Arrays.asList(\"close\", \"inTwr\"));\n" + 96 " test#N(true, true, Arrays.asList(\"close\", \"inTwr\", \"close-exception\"));\n"; 97 98 final String TEST_METHOD_TEMPLATE = 99 " private void test#N(boolean failInTwr, boolean failOnClose,\n" + 100 " List<String> expectedMessages) {\n" + 101 " List<String> messages = new ArrayList<>();\n" + 102 " try {\n" + 103 " try (CloseableImpl c = new CloseableImpl(messages, failOnClose)) {\n" + 104 " if (failInTwr)\n" + 105 " throw new IllegalStateException(\"inTwr\");\n" + 106 " }\n" + 107 " } catch (IllegalStateException ex) {\n" + 108 " messages.add(ex.getMessage());\n" + 109 " for (Throwable t : ex.getSuppressed()) {\n" + 110 " messages.add(t.getMessage());\n" + 111 " }\n" + 112 " }\n" + 113 " if (!expectedMessages.equals(messages))\n" + 114 " throw new AssertionError(\"Expected and actual messages differ; expectedMessages=\" +\n" + 115 " expectedMessages + \"; actual=\" + messages);\n" + 116 " }\n"; 117 118 final String FILE_TEMPLATE = 119 "import java.util.*;\n" + 120 "public class Test implements Runnable {\n" + 121 " public void run() {\n" + 122 "#TEST_INVOCATIONS" + 123 " }\n" + 124 "#TEST_METHODS" + 125 " static class CloseableImpl implements AutoCloseable {\n" + 126 " private final List<String> messages;\n" + 127 " private final boolean failOnClose;\n" + 128 " public CloseableImpl(List<String> messages, boolean failOnClose) {\n" + 129 " this.messages = messages;\n" + 130 " this.failOnClose = failOnClose;\n" + 131 " }\n" + 132 " @Override\n" + 133 " public void close() {\n" + 134 " messages.add(\"close\");\n" + 135 " if (failOnClose)\n" + 136 " throw new IllegalStateException(\"close-exception\");\n" + 137 " }\n" + 138 " }\n" + 139 "}\n"; 140} 141