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 * @summary Test Multi-Release jar usage in runtime 27 * @library /test/lib 28 * @library /lib/testlibrary 29 * @modules jdk.compiler 30 * @build jdk.test.lib.JDKToolFinder jdk.test.lib.JDKToolLauncher 31 * jdk.test.lib.process.OutputAnalyzer 32 * jdk.test.lib.process.ProcessTools 33 * CompilerUtils RuntimeTest 34 * @run testng RuntimeTest 35 */ 36 37 import static org.testng.Assert.*; 38 39 import java.io.BufferedReader; 40 import java.io.File; 41 import java.io.IOException; 42 import java.io.InputStream; 43 import java.io.InputStreamReader; 44 import java.lang.reflect.InvocationTargetException; 45 import java.lang.reflect.Method; 46 import java.net.URL; 47 import java.net.URLClassLoader; 48 import java.nio.file.Files; 49 import java.nio.file.Path; 50 import java.nio.file.Paths; 51 import java.nio.file.StandardCopyOption; 52 import java.util.ArrayList; 53 import java.util.Arrays; 54 import java.util.List; 55 import java.util.stream.Stream; 56 57 import org.testng.annotations.BeforeClass; 58 import org.testng.annotations.DataProvider; 59 import org.testng.annotations.Test; 60 61 import jdk.test.lib.JDKToolFinder; 62 import jdk.test.lib.JDKToolLauncher; 63 import jdk.test.lib.process.OutputAnalyzer; 64 import jdk.test.lib.process.ProcessTools; 65 66 public class RuntimeTest { 67 public static final int SUCCESS = 0; 68 private final String src = System.getProperty("test.src", "."); 69 private final String usr = System.getProperty("user.dir", "."); 70 71 @DataProvider(name = "jarFiles") 72 Object[][] jarFiles() { 73 return new Object[][] { { "MV_BOTH.jar", 9, 9, 9 }, 74 { "MV_ONLY_9.jar", 9, 9, 9 }, 75 { "NON_MV.jar", 8, 8, 8 } }; 76 } 77 78 @BeforeClass 79 protected void setUpTest() throws Throwable { 80 compile(); 81 Path classes = Paths.get("classes"); 82 jar("cfm", "MV_BOTH.jar", "manifest.txt", 83 "-C", classes.resolve("base").toString(), ".", 84 "--release", "9", "-C", classes.resolve("v9").toString(), ".", 85 "--release", "10", "-C", classes.resolve("v10").toString(), ".") 86 .shouldHaveExitValue(0); 87 88 jar("cfm", "MV_ONLY_9.jar", "manifest.txt", 89 "-C", classes.resolve("base").toString(), ".", 90 "--release", "9", "-C", classes.resolve("v9").toString(), ".") 91 .shouldHaveExitValue(0); 92 jar("cfm", "NON_MV.jar", "manifest.txt", 93 "-C", classes.resolve("base").toString(), ".") 94 .shouldHaveExitValue(0); 95 } 96 97 @Test(dataProvider = "jarFiles") 98 public void testClasspath(String jar, int mainVer, int helperVer, 99 int resVer) throws Throwable { 100 String[] command = { "-cp", jar, "testpackage.Main" }; 101 System.out.println("Command arguments:" + Arrays.asList(command)); 102 System.out.println(); 103 java(command).shouldHaveExitValue(SUCCESS) 104 .shouldContain("Main version: " + mainVer) 105 .shouldContain("Helpers version: " + helperVer) 106 .shouldContain("Resource version: " + resVer); 107 } 108 109 @Test(dataProvider = "jarFiles") 110 void testMVJarAsLib(String jar, int mainVer, int helperVer, int resVer) 111 throws Throwable { 112 String[] apps = { "UseByImport", "UseByReflection" }; 113 for (String app : apps) { 186 187 @Test(dataProvider = "jarFiles") 188 void testJjs(String jar, int mainVer, int helperVer, int resVer) 189 throws Throwable { 190 JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jjs"); 191 launcher.addToolArg("-cp").addToolArg(jar) 192 .addToolArg(src + "/data/runtimetest/MVJarJJSTestScript.js"); 193 ProcessTools.executeCommand(launcher.getCommand()) 194 .shouldHaveExitValue(SUCCESS) 195 .shouldContain("Main version: " + mainVer) 196 .shouldContain("Helpers version: " + helperVer) 197 .shouldContain("Resource version: " + resVer); 198 } 199 200 private static OutputAnalyzer jar(String... args) throws Throwable { 201 JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jar"); 202 Stream.of(args).forEach(launcher::addToolArg); 203 return ProcessTools.executeCommand(launcher.getCommand()); 204 } 205 206 private void compile() throws Throwable { 207 String[] vers = { "base", "v9", "v10" }; 208 for (String ver : vers) { 209 Path classes = Paths.get(usr, "classes", ver); 210 Files.createDirectories(classes); 211 Path source = Paths.get(src, "data", "runtimetest", ver); 212 assertTrue(CompilerUtils.compile(source, classes)); 213 Files.copy(source.resolve("versionResource"), 214 classes.resolve("versionResource"), 215 StandardCopyOption.REPLACE_EXISTING); 216 } 217 218 Path classes = Paths.get(usr, "classes", "test"); 219 Files.createDirectory(classes); 220 Path source = Paths.get(src, "data", "runtimetest", "test"); 221 assertTrue( 222 CompilerUtils.compile(source, classes, "-cp", "classes/base/")); 223 Files.copy(Paths.get(src, "data", "runtimetest", "manifest.txt"), 224 Paths.get(usr, "manifest.txt"), 225 StandardCopyOption.REPLACE_EXISTING); 226 } 227 228 OutputAnalyzer java(String... args) throws Throwable { 229 String java = JDKToolFinder.getJDKTool("java"); 230 231 List<String> commands = new ArrayList<>(); 232 commands.add(java); 233 Stream.of(args).forEach(x -> commands.add(x)); 234 return ProcessTools.executeCommand(new ProcessBuilder(commands)); 235 } 236 } | 1 /* 2 * Copyright (c) 2016, 2017, 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 * @summary Test Multi-Release jar usage in runtime 27 * @library /test/lib 28 * @modules jdk.compiler 29 * @run testng RuntimeTest 30 */ 31 32 import static org.testng.Assert.*; 33 34 import java.io.BufferedReader; 35 import java.io.File; 36 import java.io.IOException; 37 import java.io.InputStream; 38 import java.io.InputStreamReader; 39 import java.lang.reflect.InvocationTargetException; 40 import java.lang.reflect.Method; 41 import java.net.URL; 42 import java.net.URLClassLoader; 43 import java.nio.file.Files; 44 import java.nio.file.Path; 45 import java.nio.file.Paths; 46 import java.nio.file.StandardCopyOption; 47 import java.util.ArrayList; 48 import java.util.Arrays; 49 import java.util.HashMap; 50 import java.util.List; 51 import java.util.Map; 52 import java.util.stream.Collectors; 53 import java.util.stream.Stream; 54 55 import org.testng.annotations.BeforeClass; 56 import org.testng.annotations.DataProvider; 57 import org.testng.annotations.Test; 58 59 import jdk.test.lib.JDKToolFinder; 60 import jdk.test.lib.JDKToolLauncher; 61 import jdk.test.lib.compiler.CompilerUtils; 62 import jdk.test.lib.process.OutputAnalyzer; 63 import jdk.test.lib.process.ProcessTools; 64 65 public class RuntimeTest { 66 public static final int SUCCESS = 0; 67 private static final String src = System.getProperty("test.src", "."); 68 private static final String usr = System.getProperty("user.dir", "."); 69 70 private static final Path srcFileRoot = Paths.get(src, "data", "runtimetest"); 71 private static final Path genFileRoot = Paths.get(usr, "data", "runtimetest"); 72 73 private static final int OLD_RELEASE = 8; 74 private static final int CURRENT_RELEASE = Runtime.version().major(); 75 private static final int FUTURE_RELEASE = CURRENT_RELEASE + 1; 76 private static final String MRJAR_BOTH_RELEASES = "MV_BOTH.jar"; 77 private static final String MRJAR_CURRENT_RELEASE = "MV_ONLY_" + CURRENT_RELEASE + ".jar"; 78 private static final String NON_MRJAR_OLD_RELEASE = "NON_MV.jar"; 79 80 private static final int[] versions = {OLD_RELEASE, CURRENT_RELEASE, FUTURE_RELEASE}; 81 private static final Map<String, String> templateSourceMap = new HashMap<>() { 82 { 83 put("helper.template", "Helper.java"); 84 put("main.template", "Main.java"); 85 put("resource.template", "versionResource"); 86 } 87 }; 88 89 @DataProvider(name = "jarFiles") 90 Object[][] jarFiles() { 91 return new Object[][]{ 92 {MRJAR_BOTH_RELEASES, CURRENT_RELEASE, CURRENT_RELEASE, CURRENT_RELEASE}, 93 {MRJAR_CURRENT_RELEASE, CURRENT_RELEASE, CURRENT_RELEASE, CURRENT_RELEASE}, 94 {NON_MRJAR_OLD_RELEASE, OLD_RELEASE, OLD_RELEASE, OLD_RELEASE} 95 }; 96 } 97 98 @BeforeClass 99 protected void setUpTest() throws Throwable { 100 createJarSourceFiles(); 101 compile(); 102 Path classes = Paths.get("classes"); 103 jar("cfm", MRJAR_BOTH_RELEASES, "manifest.txt", 104 "-C", classes.resolve("v" + OLD_RELEASE).toString(), ".", 105 "--release", "" + CURRENT_RELEASE, "-C", classes.resolve("v" + CURRENT_RELEASE).toString(), ".", 106 "--release", "" + FUTURE_RELEASE, "-C", classes.resolve("v" + FUTURE_RELEASE).toString(), ".") 107 .shouldHaveExitValue(0); 108 109 jar("cfm", MRJAR_CURRENT_RELEASE, "manifest.txt", 110 "-C", classes.resolve("v" + OLD_RELEASE).toString(), ".", 111 "--release", "" + CURRENT_RELEASE, "-C", classes.resolve("v" + CURRENT_RELEASE).toString(), ".") 112 .shouldHaveExitValue(0); 113 jar("cfm", NON_MRJAR_OLD_RELEASE, "manifest.txt", 114 "-C", classes.resolve("v" + OLD_RELEASE).toString(), ".") 115 .shouldHaveExitValue(0); 116 } 117 118 @Test(dataProvider = "jarFiles") 119 public void testClasspath(String jar, int mainVer, int helperVer, 120 int resVer) throws Throwable { 121 String[] command = { "-cp", jar, "testpackage.Main" }; 122 System.out.println("Command arguments:" + Arrays.asList(command)); 123 System.out.println(); 124 java(command).shouldHaveExitValue(SUCCESS) 125 .shouldContain("Main version: " + mainVer) 126 .shouldContain("Helpers version: " + helperVer) 127 .shouldContain("Resource version: " + resVer); 128 } 129 130 @Test(dataProvider = "jarFiles") 131 void testMVJarAsLib(String jar, int mainVer, int helperVer, int resVer) 132 throws Throwable { 133 String[] apps = { "UseByImport", "UseByReflection" }; 134 for (String app : apps) { 207 208 @Test(dataProvider = "jarFiles") 209 void testJjs(String jar, int mainVer, int helperVer, int resVer) 210 throws Throwable { 211 JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jjs"); 212 launcher.addToolArg("-cp").addToolArg(jar) 213 .addToolArg(src + "/data/runtimetest/MVJarJJSTestScript.js"); 214 ProcessTools.executeCommand(launcher.getCommand()) 215 .shouldHaveExitValue(SUCCESS) 216 .shouldContain("Main version: " + mainVer) 217 .shouldContain("Helpers version: " + helperVer) 218 .shouldContain("Resource version: " + resVer); 219 } 220 221 private static OutputAnalyzer jar(String... args) throws Throwable { 222 JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jar"); 223 Stream.of(args).forEach(launcher::addToolArg); 224 return ProcessTools.executeCommand(launcher.getCommand()); 225 } 226 227 private static String platformPath(String p) { 228 return p.replace("/", File.separator); 229 } 230 231 private static void createJarSourceFiles() throws IOException { 232 for (int ver : versions) { 233 for (Map.Entry<String, String> fileMap : templateSourceMap.entrySet()) { 234 String genFileName = fileMap.getValue(); 235 Path template = srcFileRoot.resolve(fileMap.getKey()); 236 Path out = genFileName.endsWith("java") 237 ? genFileRoot.resolve(platformPath("v" + ver + "/testpackage/" + genFileName)) 238 : genFileRoot.resolve(platformPath("v" + ver + "/" + genFileName)); 239 Files.createDirectories(out.getParent()); 240 List<String> lines = Files.lines(template) 241 .map(s -> s.replaceAll("\\$version", String.valueOf(ver))) 242 .collect(Collectors.toList()); 243 Files.write(out, lines); 244 } 245 } 246 } 247 248 private void compile() throws Throwable { 249 for (int ver : versions) { 250 Path classes = Paths.get(usr, "classes", "v" + ver); 251 Files.createDirectories(classes); 252 Path source = genFileRoot.resolve("v" + ver); 253 assertTrue(CompilerUtils.compile(source, classes)); 254 Files.copy(source.resolve("versionResource"), 255 classes.resolve("versionResource"), 256 StandardCopyOption.REPLACE_EXISTING); 257 } 258 259 Path classes = Paths.get(usr, "classes", "test"); 260 Files.createDirectory(classes); 261 Path source = srcFileRoot.resolve("test"); 262 assertTrue( 263 CompilerUtils.compile(source, classes, "-cp", "classes/v" + OLD_RELEASE)); 264 Files.copy(srcFileRoot.resolve("manifest.txt"), 265 Paths.get(usr, "manifest.txt"), 266 StandardCopyOption.REPLACE_EXISTING); 267 } 268 269 OutputAnalyzer java(String... args) throws Throwable { 270 String java = JDKToolFinder.getJDKTool("java"); 271 272 List<String> commands = new ArrayList<>(); 273 commands.add(java); 274 Stream.of(args).forEach(x -> commands.add(x)); 275 return ProcessTools.executeCommand(new ProcessBuilder(commands)); 276 } 277 } |