1 /* 2 * Copyright (c) 2016, 2018, 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 8153654 8176333 27 * @summary Tests for jdeps tool with multi-release jar files 28 * @modules jdk.jdeps/com.sun.tools.jdeps 29 * @library mrjar mrjar/base mrjar/9 mrjar/10 mrjar/v9 mrjar/v10 30 * @build test.* p.* q.* foo/* Main 31 * @run testng MultiReleaseJar 32 */ 33 34 import org.testng.Assert; 35 import org.testng.annotations.AfterClass; 36 import org.testng.annotations.BeforeClass; 37 import org.testng.annotations.Test; 38 39 import java.io.File; 40 import java.io.InputStream; 41 import java.nio.file.Path; 42 import java.nio.file.Paths; 43 import java.util.stream.Stream; 44 45 public class MultiReleaseJar { 46 Path mrjar; 47 String testJdk; 48 String fileSep; 49 Path cmdPath; 50 51 @BeforeClass 52 public void initialize() throws Exception { 53 String testClassPath = System.getProperty("test.class.path", ""); 54 mrjar = Stream.of(testClassPath.split(File.pathSeparator)) 55 .map(Paths::get) 56 .filter(e -> e.endsWith("mrjar")) 57 .findAny() 58 .orElseThrow(() -> new InternalError("mrjar not found")); 59 testJdk = System.getProperty("test.jdk"); 60 fileSep = System.getProperty("file.separator"); 61 cmdPath = Paths.get(testJdk, "bin"); 62 63 // build Version.jar, Version_9.jar and main.jar 64 Result r = run("jar -cf Version.jar -C base test --release 9 -C 9 test --release 10 -C 10 test"); 65 checkResult(r); 66 67 r = run("jar -cf Version_9.jar -C base test --release 9 -C 9 test"); 68 checkResult(r); 69 70 r = run("jar -cf Main.jar Main.class"); 71 checkResult(r); 72 73 r = run("jar -cf Foo.jar -C base p"); 74 checkResult(r); 75 76 Path foo = Paths.get(System.getProperty("test.classes")).resolve("modules").resolve("foo"); 77 r = run("jar -uf Foo.jar --release 9 -C " + foo.toString() + " module-info.class --release 10 -C v10 q"); 78 checkResult(r); 79 } 80 81 @Test 82 public void basic() throws Exception { 83 Result r = run("jdeps --multi-release 9 -v missing.jar"); 84 checkResult(r, false, "Warning: Path does not exist: missing.jar"); 85 86 r = run("jdeps -v Version.jar"); 87 checkResult(r, false, "--multi-release option is not set"); 88 89 r = run("jdeps --multi-release base -v Version.jar"); 90 checkResult(r, true, 91 "Version.jar ->", 92 "test.Version", 93 "test.Version" 94 ); 95 96 r = run("jdeps --multi-release 9 -v Version.jar"); 97 checkResult(r, true, 98 "Version.jar ->", 99 "9/test.NonPublic", 100 "9/test.NonPublic", 101 "9/test.Version", 102 "9/test.Version", 103 "9/test.Version", 104 "9/test.Version" 105 ); 106 107 r = run("jdeps --multi-release 10 -v Version.jar"); 108 checkResult(r, true, 109 "Version.jar ->", 110 "10/test.Version", 111 "10/test.Version", 112 "10/test.Version", 113 "10/test.Version", 114 "9/test.NonPublic", 115 "9/test.NonPublic" 116 ); 117 118 r = run("jdeps --multi-release 8 -v Version.jar"); 119 checkResult(r, false, "Error: invalid argument for option: 8"); 120 121 r = run("jdeps --multi-release 9.1 -v Version.jar"); 122 checkResult(r, false, "Error: invalid argument for option: 9.1"); 123 124 runJdeps("Main.class"); 125 runJdeps("Main.jar"); 126 } 127 128 129 private void runJdeps(String path) throws Exception { 130 Result r = run("jdeps -v -R -cp Version.jar " + path); 131 checkResult(r, false, "--multi-release option is not set"); 132 133 r = run("jdeps -v -R -cp Version.jar --module-path Foo.jar -multi-release 9 " + path); 134 checkResult(r, false, 135 "Error: unknown option: -multi-release", 136 "Usage: jdeps <options> <path", 137 "use --help" 138 ); 139 140 r = run("jdeps -v -R -cp Version.jar --module-path Foo.jar --multi-release 9 " + path); 141 142 String name = path; 143 int index = path.lastIndexOf('/'); 144 if (index >= 0) { 145 name = path.substring(index + 1, path.length()); 146 } 147 checkResult(r, true, 148 name + " -> Version.jar", 149 name + " -> foo", 150 name + " -> java.base", 151 "Main", 152 "Main", 153 "Main", 154 "Main", 155 "Version.jar -> java.base", 156 "9/test.NonPublic", 157 "9/test.NonPublic", 158 "9/test.Version", 159 "9/test.Version", 160 "9/test.Version", 161 "9/test.Version", 162 "foo", 163 "Foo.jar", 164 "requires mandated java.base", 165 "foo -> java.base", 166 "p.Foo" 167 ); 168 169 r = run("jdeps -v -R -cp Version.jar --module-path Foo.jar --multi-release 10 " + path); 170 checkResult(r, true, 171 name + " -> Version.jar", 172 name + " -> foo", 173 name + " -> java.base", 174 "Main", 175 "Main", 176 "Main", 177 "Main", 178 "Version.jar ->", 179 "10/test.Version", 180 "10/test.Version", 181 "10/test.Version", 182 "10/test.Version", 183 "9/test.NonPublic", 184 "9/test.NonPublic", 185 "foo", 186 "Foo.jar", 187 "requires mandated java.base", 188 "foo -> java.base", 189 "p.Foo" 190 ); 191 192 r = run("jdeps -v -R -cp Version.jar --module-path Foo.jar --multi-release base " + path); 193 checkResult(r, true, 194 name + " -> Version.jar", 195 name + " -> foo", 196 name + " -> java.base", 197 "Main", 198 "Main", 199 "Main", 200 "Main", 201 "Version.jar ->", 202 "test.Version", 203 "test.Version", 204 "foo", 205 "Foo.jar", 206 "requires mandated java.base", 207 "foo -> java.base", 208 "p.Foo" 209 ); 210 211 r = run("jdeps -v -R -cp Version.jar --module-path Foo.jar --multi-release 9.1 " + path); 212 checkResult(r, false, "Error: invalid argument for option: 9.1"); 213 214 // Version_9.jar does not have any version 10 entry 215 r = run("jdeps -v -R -cp Version_9.jar --module-path Foo.jar --multi-release 10 " + path); 216 checkResult(r, true, 217 name + " -> Version_9.jar", 218 name + " -> foo", 219 name + " -> java.base", 220 "Main", 221 "Main", 222 "Main", 223 "Main", 224 "Version_9.jar ->", 225 "9/test.NonPublic", 226 "9/test.NonPublic", 227 "9/test.Version", 228 "9/test.Version", 229 "9/test.Version", 230 "9/test.Version", 231 "foo", 232 "Foo.jar", 233 "requires mandated java.base", 234 "foo -> java.base", 235 "p.Foo" 236 ); 237 } 238 239 @Test 240 public void ps_and_qs() throws Exception { 241 // build the jar file 242 Result r = run("jar -cf PQ.jar -C base p --release 9 -C v9 p -C v9 q --release 10 -C v10 q"); 243 checkResult(r); 244 245 r = run("jdeps -v -R -cp PQ.jar --multi-release base PQ.jar"); 246 checkResult(r, true, 247 "PQ.jar -> java.base", 248 "p.Foo" 249 ); 250 251 r = run("jdeps -v -R -cp PQ.jar --multi-release 9 PQ.jar"); 252 checkResult(r, true, 253 "PQ.jar -> java.base", 254 "9/p.Foo", 255 "9/p.Foo", 256 "9/q.Bar" 257 ); 258 259 260 r = run("jdeps -v -R -cp PQ.jar --multi-release 10 PQ.jar"); 261 checkResult(r, true, 262 "PQ.jar -> java.base", 263 "10/q.Bar", 264 "10/q.Bar", 265 "10/q.Gee", 266 "9/p.Foo", 267 "9/p.Foo" 268 ); 269 } 270 271 @Test 272 public void modularJar() throws Exception { 273 Result r = run("jdeps -v --multi-release 10 --module-path Foo.jar -m foo"); 274 checkResult(r, true, 275 "foo", // module name 276 "Foo.jar", // the path to Foo.jar 277 "requires mandated java.base", // module dependences 278 "foo -> java.base", 279 "10/q.Bar", 280 "10/q.Bar", 281 "10/q.Gee", 282 "p.Foo" 283 ); 284 285 r = run("jdeps --multi-release 9 -cp Version.jar --module-path Foo.jar Main.jar"); 286 checkResult(r, true, 287 "Main.jar -> Version.jar", 288 "Main.jar -> foo", 289 "Main.jar -> java.base", 290 "-> java.lang", 291 "-> p", 292 "-> test" 293 ); 294 295 r = run("jdeps --multi-release 10 -cp Version.jar --module-path Foo.jar Main.jar"); 296 checkResult(r, true, 297 "Main.jar -> Version.jar", 298 "Main.jar -> foo", 299 "Main.jar -> java.base", 300 "-> java.lang", 301 "-> p", 302 "-> test" 303 ); 304 } 305 306 static class Result { 307 final String cmd; 308 final int rc; 309 final String out; 310 final String err; 311 Result(String cmd, int rc, String out, String err) { 312 this.cmd = cmd; 313 this.rc = rc; 314 this.out = out; 315 this.err = err; 316 } 317 } 318 319 Result run(String cmd) throws Exception { 320 String[] cmds = cmd.split(" +"); 321 cmds[0] = cmdPath.resolve(cmds[0]).toString(); 322 ProcessBuilder pb = new ProcessBuilder(cmds); 323 pb.directory(mrjar.toFile()); 324 Process p = null; 325 try { 326 p = pb.start(); 327 p.waitFor(); 328 329 String out; 330 try (InputStream is = p.getInputStream()) { 331 out = new String(is.readAllBytes()); 332 } 333 String err; 334 try (InputStream is = p.getErrorStream()) { 335 err = new String(is.readAllBytes()); 336 } 337 return new Result(cmd, p.exitValue(), out, err); 338 } catch (Throwable t) { 339 if (p != null) { 340 p.destroyForcibly().waitFor(); 341 } 342 throw t; 343 } 344 } 345 346 void checkResult(Result r) throws Exception { 347 System.out.println(r.cmd); 348 System.out.println(r.out); 349 if (r.rc != 0) { 350 System.out.println(r.err); 351 throw new Exception("rc=" + r.rc); 352 } 353 System.out.println(); 354 } 355 356 void checkResult(Result r, boolean checkrc, String... lines) throws Exception { 357 System.out.println(r.cmd); 358 System.out.println(r.out); 359 if (checkrc && r.rc != 0) { 360 System.out.println(r.err); 361 throw new Exception("rc=" + r.rc); 362 } 363 String[] out = r.out.split("\r?\n"); 364 Assert.assertEquals(out.length, lines.length); 365 int n = 0; 366 for (String line : lines) { 367 Assert.assertTrue(out[n++].contains(line), "\"" + line + "\""); 368 } 369 System.out.println(); 370 } 371 }