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 8149757 27 * @summary Test that javac uses the correct version of a class from a 28 * multi-release jar on classpath 29 * @library /tools/lib 30 * @modules jdk.compiler/com.sun.tools.javac.api 31 * jdk.compiler/com.sun.tools.javac.main 32 * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask 33 * @run testng MultiReleaseJarTest 34 */ 35 36 import org.testng.annotations.AfterClass; 37 import org.testng.annotations.BeforeClass; 38 import org.testng.annotations.DataProvider; 39 import org.testng.annotations.Test; 40 41 import toolbox.JarTask; 42 import toolbox.JavacTask; 43 import toolbox.Task; 44 import toolbox.ToolBox; 45 46 47 public class MultiReleaseJarTest { 48 49 private final String main1 = 50 "class Main {\n" + 51 " Info info = new Info();\n" + 52 " \n" + 53 " void run() {\n" + 54 " System.out.println(info.get());\n" + 55 " }\n" + 56 "}\n"; 57 58 private final String main2 = 59 "class Main {\n" + 60 " Info info = new Info();\n" + 61 " \n" + 62 " void run() {\n" + 63 " System.out.println(info.getInfo());\n" + 64 " }\n" + 65 "}\n"; 66 67 private final String info1 = 68 "class Info {\n" + 69 " String get() {\n" + 70 " return \"some info\";\n" + 71 " }\n" + 72 "}\n"; 73 74 private final String info2 = 75 "class Info {\n" + 76 " String getInfo() {\n" + 77 " return \"some info\";\n" + 78 " }\n" + 79 "}\n"; 80 81 private final String manifest = 82 "Manifest-Version: 1.0\n" + 83 "Multi-Release: true\n"; 84 85 private final ToolBox tb = new ToolBox(); 86 87 @BeforeClass 88 public void setup() throws Exception { 89 tb.createDirectories("classes", "classes/META-INF/versions/9"); 90 new JavacTask(tb) 91 .outdir("classes") 92 .sources(info1) 93 .run(); 94 new JavacTask(tb) 95 .outdir("classes/META-INF/versions/9") 96 .sources(info2) 97 .run(); 98 // This is a bogus multi-release jar file since the two Info classes 99 // do not have the same public interface 100 new JarTask(tb, "multi-release.jar") 101 .manifest(manifest) 102 .baseDir("classes") 103 .files("Info.class", "META-INF/versions/9/Info.class") 104 .run(); 105 tb.deleteFiles( 106 "classes/META-INF/versions/9/Info.class", 107 "classes/META-INF/versions/9", 108 "classes/META-INF/versions", 109 "classes/META-INF", 110 "classes/Info.class" 111 ); 112 } 113 114 @AfterClass 115 public void teardown() throws Exception { 116 tb.deleteFiles( 117 "multi-release.jar", 118 "classes/Main.class", 119 "classes" 120 ); 121 } 122 123 @Test(dataProvider="modes") 124 // javac -d classes -cp multi-release.jar Main.java -> fails 125 public void main1Runtime(Task.Mode mode) throws Exception { 126 tb.writeFile("Main.java", main1); 127 Task.Result result = new JavacTask(tb, mode) 128 .outdir("classes") 129 .classpath("multi-release.jar") 130 .files("Main.java") 131 .run(Task.Expect.FAIL, 1); 132 result.writeAll(); 133 tb.deleteFiles("Main.java"); 134 135 } 136 137 @Test(dataProvider="modes") 138 // javac -d classes --release 8 -cp multi-release.jar Main.java -> succeeds 139 public void main1Release8(Task.Mode mode) throws Exception { 140 tb.writeFile("Main.java", main1); 141 Task.Result result = new JavacTask(tb, mode) 142 .outdir("classes") 143 .options("--release", "8") 144 .classpath("multi-release.jar") 145 .files("Main.java") 146 .run(); 147 result.writeAll(); 148 tb.deleteFiles("Main.java"); 149 } 150 151 @Test(dataProvider="modes") 152 // javac -d classes --release 9 -cp multi-release.jar Main.java -> fails 153 public void main1Release9(Task.Mode mode) throws Exception { 154 tb.writeFile("Main.java", main1); 155 Task.Result result = new JavacTask(tb, mode) 156 .outdir("classes") 157 .options("--release", "9") 158 .classpath("multi-release.jar") 159 .files("Main.java") 160 .run(Task.Expect.FAIL, 1); 161 result.writeAll(); 162 tb.deleteFiles("Main.java"); 163 } 164 165 @Test(dataProvider="modes") 166 // javac -d classes -cp multi-release.jar Main.java -> succeeds 167 public void main2Runtime(Task.Mode mode) throws Exception { 168 tb.writeFile("Main.java", main2); 169 Task.Result result = new JavacTask(tb, mode) 170 .outdir("classes") 171 .classpath("multi-release.jar") 172 .files("Main.java") 173 .run(); 174 result.writeAll(); 175 tb.deleteFiles("Main.java"); 176 177 } 178 179 @Test(dataProvider="modes") 180 // javac -d classes --release 8 -cp multi-release.jar Main.java -> fails 181 public void main2Release8(Task.Mode mode) throws Exception { 182 tb.writeFile("Main.java", main2); 183 Task.Result result = new JavacTask(tb, mode) 184 .outdir("classes") 185 .options("--release", "8") 186 .classpath("multi-release.jar") 187 .files("Main.java") 188 .run(Task.Expect.FAIL, 1); 189 result.writeAll(); 190 tb.deleteFiles("Main.java"); 191 } 192 193 @Test(dataProvider="modes") 194 // javac -d classes --release 9 -cp multi-release.jar Main.java -> succeeds 195 public void main2Release9(Task.Mode mode) throws Exception { 196 tb.writeFile("Main.java", main2); 197 Task.Result result = new JavacTask(tb, mode) 198 .outdir("classes") 199 .options("--release", "9") 200 .classpath("multi-release.jar") 201 .files("Main.java") 202 .run(); 203 result.writeAll(); 204 tb.deleteFiles("Main.java"); 205 } 206 207 @DataProvider(name="modes") 208 public Object[][] createModes() { 209 return new Object[][] { 210 new Object[] {Task.Mode.API}, 211 new Object[] {Task.Mode.CMDLINE}, 212 new Object[] {Task.Mode.EXEC}, 213 }; 214 } 215 } 216