AutomaticModules.java revision 3792:d516975e8110
153537Sbrian/* 280728Sbrian * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 353537Sbrian * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 453537Sbrian * 553537Sbrian * This code is free software; you can redistribute it and/or modify it 653537Sbrian * under the terms of the GNU General Public License version 2 only, as 753537Sbrian * published by the Free Software Foundation. 853537Sbrian * 953537Sbrian * This code is distributed in the hope that it will be useful, but WITHOUT 1053537Sbrian * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1153537Sbrian * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1253537Sbrian * version 2 for more details (a copy is included in the LICENSE file that 1353537Sbrian * accompanied this code). 1453537Sbrian * 1553537Sbrian * You should have received a copy of the GNU General Public License version 1653537Sbrian * 2 along with this work; if not, write to the Free Software Foundation, 1753537Sbrian * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1853537Sbrian * 1953537Sbrian * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2053537Sbrian * or visit www.oracle.com if you need additional information or have any 2153537Sbrian * questions. 2253537Sbrian */ 2353537Sbrian 2453537Sbrian/** 2553537Sbrian * @test 2653537Sbrian * @bug 8155026 2753537Sbrian * @summary Test automatic modules 2853537Sbrian * @library /tools/lib 2953537Sbrian * @modules 3079529Sru * java.desktop 3153537Sbrian * jdk.compiler/com.sun.tools.javac.api 3253537Sbrian * jdk.compiler/com.sun.tools.javac.main 3353537Sbrian * @build toolbox.ToolBox toolbox.JavacTask toolbox.JarTask ModuleTestBase 3453537Sbrian * @run main AutomaticModules 3568949Sru */ 3670227Sru 3753609Sbrianimport java.nio.file.Files; 3853537Sbrianimport java.nio.file.Path; 3981251Sruimport java.util.Arrays; 4066602Sbrianimport java.util.List; 4153537Sbrian 4253537Sbrianimport toolbox.JarTask; 4353537Sbrianimport toolbox.JavacTask; 4453537Sbrianimport toolbox.Task; 4553537Sbrian 4699500Scharnierpublic class AutomaticModules extends ModuleTestBase { 4753537Sbrian 4853537Sbrian public static void main(String... args) throws Exception { 4986783Sru AutomaticModules t = new AutomaticModules(); 5086783Sru t.runTests(); 5180728Sbrian } 5280728Sbrian 5353537Sbrian @Test 5480728Sbrian public void testSimple(Path base) throws Exception { 5580728Sbrian Path legacySrc = base.resolve("legacy-src"); 5677760Ssobomax tb.writeJavaFiles(legacySrc, 5753537Sbrian "package api; import java.awt.event.ActionListener; public abstract class Api implements ActionListener {}"); 5853537Sbrian Path legacyClasses = base.resolve("legacy-classes"); 5999500Scharnier Files.createDirectories(legacyClasses); 6053537Sbrian 6199500Scharnier String log = new JavacTask(tb) 6253537Sbrian .options() 6353537Sbrian .outdir(legacyClasses) 6453537Sbrian .files(findJavaFiles(legacySrc)) 6553537Sbrian .run() 6686783Sru .writeAll() 6753537Sbrian .getOutput(Task.OutputKind.DIRECT); 6853537Sbrian 6953537Sbrian if (!log.isEmpty()) { 7053537Sbrian throw new Exception("unexpected output: " + log); 7180728Sbrian } 7280728Sbrian 7353537Sbrian Path modulePath = base.resolve("module-path"); 7453537Sbrian 7553537Sbrian Files.createDirectories(modulePath); 7653537Sbrian 7753537Sbrian Path jar = modulePath.resolve("test-api-1.0.jar"); 7886783Sru 7980728Sbrian new JarTask(tb, jar) 8080728Sbrian .baseDir(legacyClasses) 8181251Sru .files("api/Api.class") 8281251Sru .run(); 8353537Sbrian 8453537Sbrian Path moduleSrc = base.resolve("module-src"); 8580728Sbrian Path m1 = moduleSrc.resolve("m1"); 8686783Sru 8786783Sru Path classes = base.resolve("classes"); 8886783Sru 8979754Sdd Files.createDirectories(classes); 9053537Sbrian 9153537Sbrian tb.writeJavaFiles(m1, 9286783Sru "module m1 { requires test.api; requires java.desktop; }", 9353537Sbrian "package impl; public class Impl { public void e(api.Api api) { api.actionPerformed(null); } }"); 9480728Sbrian 9580728Sbrian new JavacTask(tb) 9680728Sbrian .options("--module-source-path", moduleSrc.toString(), "--module-path", modulePath.toString()) 9780728Sbrian .outdir(classes) 9880728Sbrian .files(findJavaFiles(moduleSrc)) 9980728Sbrian .run() 10053537Sbrian .writeAll(); 10180728Sbrian } 10280728Sbrian 10353537Sbrian @Test 10480728Sbrian public void testUnnamedModule(Path base) throws Exception { 10580728Sbrian Path legacySrc = base.resolve("legacy-src"); 10680728Sbrian tb.writeJavaFiles(legacySrc, 10780728Sbrian "package api; public abstract class Api { public void run(CharSequence str) { } private void run(base.Base base) { } }", 10853537Sbrian "package base; public interface Base { public void run(); }"); 10953537Sbrian Path legacyClasses = base.resolve("legacy-classes"); 11053537Sbrian Files.createDirectories(legacyClasses); 11181251Sru 11281251Sru String log = new JavacTask(tb) 11353537Sbrian .options() 11453537Sbrian .outdir(legacyClasses) 11590975Sbrian .files(findJavaFiles(legacySrc)) 11686783Sru .run() 11790975Sbrian .writeAll() 11890975Sbrian .getOutput(Task.OutputKind.DIRECT); 11990975Sbrian 12090975Sbrian if (!log.isEmpty()) { 12186756Sbrian throw new Exception("unexpected output: " + log); 12253537Sbrian } 12353537Sbrian 12453537Sbrian Path modulePath = base.resolve("module-path"); 12553537Sbrian 12653537Sbrian Files.createDirectories(modulePath); 12753537Sbrian 12853537Sbrian Path apiJar = modulePath.resolve("test-api-1.0.jar"); 12986783Sru 13053537Sbrian new JarTask(tb, apiJar) 13153537Sbrian .baseDir(legacyClasses) 13253537Sbrian .files("api/Api.class") 13353537Sbrian .run(); 13480728Sbrian 13580728Sbrian Path baseJar = base.resolve("base.jar"); 13653537Sbrian 13786783Sru new JarTask(tb, baseJar) 13853537Sbrian .baseDir(legacyClasses) 13953537Sbrian .files("base/Base.class") 14080728Sbrian .run(); 14180728Sbrian 14253537Sbrian Path moduleSrc = base.resolve("module-src"); 14386783Sru Path m1 = moduleSrc.resolve("m1"); 14453537Sbrian 14553537Sbrian Path classes = base.resolve("classes"); 14653537Sbrian 14753537Sbrian Files.createDirectories(classes); 14853537Sbrian 14986783Sru tb.writeJavaFiles(m1, 15053537Sbrian "module m1 { requires test.api; }", 15153537Sbrian "package impl; public class Impl { public void e(api.Api api) { api.run(\"\"); } }"); 15266602Sbrian 15366602Sbrian new JavacTask(tb) 15486783Sru .options("--module-source-path", moduleSrc.toString(), "--module-path", modulePath.toString(), "--class-path", baseJar.toString()) 15566602Sbrian .outdir(classes) 15666602Sbrian .files(findJavaFiles(moduleSrc)) 15766602Sbrian .run() 15853609Sbrian .writeAll(); 15953609Sbrian } 16053609Sbrian 16153609Sbrian @Test 16253609Sbrian public void testModuleInfoFromClassFileDependsOnAutomatic(Path base) throws Exception { 16353609Sbrian Path automaticSrc = base.resolve("automaticSrc"); 16453537Sbrian tb.writeJavaFiles(automaticSrc, "package api; public class Api {}"); 16553537Sbrian Path automaticClasses = base.resolve("automaticClasses"); 16653537Sbrian tb.createDirectories(automaticClasses); 16753537Sbrian 16853537Sbrian String automaticLog = new JavacTask(tb) 16953537Sbrian .outdir(automaticClasses) 17053537Sbrian .files(findJavaFiles(automaticSrc)) 17180728Sbrian .run() 17280728Sbrian .writeAll() 17353537Sbrian .getOutput(Task.OutputKind.DIRECT); 17486783Sru 17553537Sbrian if (!automaticLog.isEmpty()) 176141851Sru throw new Exception("expected output not found: " + automaticLog); 17753537Sbrian 17886783Sru Path modulePath = base.resolve("module-path"); 17953537Sbrian 18066602Sbrian Files.createDirectories(modulePath); 18166602Sbrian 18266602Sbrian Path automaticJar = modulePath.resolve("automatic-1.0.jar"); 18366602Sbrian 18453537Sbrian new JarTask(tb, automaticJar) 18553537Sbrian .baseDir(automaticClasses) 18653537Sbrian .files("api/Api.class") 18786783Sru .run(); 18886783Sru 18986783Sru Path depSrc = base.resolve("depSrc"); 19086783Sru Path depClasses = base.resolve("depClasses"); 19153537Sbrian 19253537Sbrian Files.createDirectories(depSrc); 19353537Sbrian Files.createDirectories(depClasses); 19453537Sbrian 19586783Sru tb.writeJavaFiles(depSrc, 19653537Sbrian "module m1 { requires transitive automatic; }", 19766602Sbrian "package dep; public class Dep { api.Api api; }"); 19853537Sbrian 19977760Ssobomax new JavacTask(tb) 20077760Ssobomax .options("--module-path", modulePath.toString()) 20177760Ssobomax .outdir(depClasses) 20279211Sru .files(findJavaFiles(depSrc)) 20353537Sbrian .run() 20453537Sbrian .writeAll(); 205140414Sru 206140414Sru Path moduleJar = modulePath.resolve("m1.jar"); 207140414Sru 208140414Sru new JarTask(tb, moduleJar) 209140414Sru .baseDir(depClasses) 210140414Sru .files("module-info.class", "dep/Dep.class") 211140414Sru .run(); 21253537Sbrian 21353537Sbrian Path testSrc = base.resolve("testSrc"); 21453537Sbrian Path testClasses = base.resolve("testClasses"); 21580728Sbrian 21680728Sbrian Files.createDirectories(testSrc); 21753537Sbrian Files.createDirectories(testClasses); 21880728Sbrian 21980728Sbrian tb.writeJavaFiles(testSrc, 220 "module m2 { requires automatic; }", 221 "package test; public class Test { }"); 222 223 new JavacTask(tb) 224 .options("--module-path", modulePath.toString()) 225 .outdir(testClasses) 226 .files(findJavaFiles(testSrc)) 227 .run() 228 .writeAll(); 229 } 230 231 @Test 232 public void testAutomaticAndNamedModules(Path base) throws Exception { 233 Path modulePath = base.resolve("module-path"); 234 235 Files.createDirectories(modulePath); 236 237 for (char c : new char[] {'A', 'B'}) { 238 Path automaticSrc = base.resolve("automaticSrc" + c); 239 tb.writeJavaFiles(automaticSrc, "package api" + c + "; public class Api {}"); 240 Path automaticClasses = base.resolve("automaticClasses" + c); 241 tb.createDirectories(automaticClasses); 242 243 String automaticLog = new JavacTask(tb) 244 .outdir(automaticClasses) 245 .files(findJavaFiles(automaticSrc)) 246 .run() 247 .writeAll() 248 .getOutput(Task.OutputKind.DIRECT); 249 250 if (!automaticLog.isEmpty()) 251 throw new Exception("expected output not found: " + automaticLog); 252 253 Path automaticJar = modulePath.resolve("automatic" + c + "-1.0.jar"); 254 255 new JarTask(tb, automaticJar) 256 .baseDir(automaticClasses) 257 .files("api" + c + "/Api.class") 258 .run(); 259 } 260 261 Path moduleSrc = base.resolve("module-src"); 262 263 tb.writeJavaFiles(moduleSrc.resolve("m1"), 264 "module m1 { requires static automaticA; }", 265 "package impl; public class Impl { apiA.Api a; apiB.Api b; m2.M2 m;}"); 266 267 tb.writeJavaFiles(moduleSrc.resolve("m2"), 268 "module m2 { exports m2; }", 269 "package m2; public class M2 { }"); 270 271 Path classes = base.resolve("classes"); 272 273 Files.createDirectories(classes); 274 275 List<String> log = new JavacTask(tb) 276 .options("--module-source-path", moduleSrc.toString(), 277 "--module-path", modulePath.toString(), 278 "--add-modules", "automaticB", 279 "-XDrawDiagnostics") 280 .outdir(classes) 281 .files(findJavaFiles(moduleSrc)) 282 .run(Task.Expect.FAIL) 283 .writeAll() 284 .getOutputLines(Task.OutputKind.DIRECT); 285 286 List<String> expected = Arrays.asList("Impl.java:1:61: compiler.err.not.def.access.package.cant.access: m2.M2, m2", 287 "1 error"); 288 289 if (!expected.equals(log)) { 290 throw new Exception("expected output not found: " + log); 291 } 292 293 log = new JavacTask(tb) 294 .options("--module-source-path", moduleSrc.toString(), 295 "--module-path", modulePath.toString(), 296 "-XDrawDiagnostics") 297 .outdir(classes) 298 .files(findJavaFiles(moduleSrc)) 299 .run(Task.Expect.FAIL) 300 .writeAll() 301 .getOutputLines(Task.OutputKind.DIRECT); 302 303 expected = Arrays.asList("Impl.java:1:51: compiler.err.doesnt.exist: apiB", 304 "Impl.java:1:61: compiler.err.not.def.access.package.cant.access: m2.M2, m2", 305 "2 errors"); 306 307 if (!expected.equals(log)) { 308 throw new Exception("expected output not found: " + log); 309 } 310 } 311 312 @Test 313 public void testDropTrailingVersion(Path base) throws Exception { 314 Path legacySrc = base.resolve("legacy-src"); 315 tb.writeJavaFiles(legacySrc, 316 "package api; public class Api {}"); 317 Path legacyClasses = base.resolve("legacy-classes"); 318 Files.createDirectories(legacyClasses); 319 320 String log = new JavacTask(tb) 321 .options() 322 .outdir(legacyClasses) 323 .files(findJavaFiles(legacySrc)) 324 .run() 325 .writeAll() 326 .getOutput(Task.OutputKind.DIRECT); 327 328 if (!log.isEmpty()) { 329 throw new Exception("unexpected output: " + log); 330 } 331 332 Path modulePath = base.resolve("module-path"); 333 334 Files.createDirectories(modulePath); 335 336 Path jar = modulePath.resolve("test1.jar"); 337 338 new JarTask(tb, jar) 339 .baseDir(legacyClasses) 340 .files("api/Api.class") 341 .run(); 342 343 Path moduleSrc = base.resolve("module-src"); 344 Path m = moduleSrc.resolve("m"); 345 346 Path classes = base.resolve("classes"); 347 348 Files.createDirectories(classes); 349 350 tb.writeJavaFiles(m, 351 "module m { requires test; }", 352 "package impl; public class Impl { public void e(api.Api api) { } }"); 353 354 new JavacTask(tb) 355 .options("--module-source-path", moduleSrc.toString(), "--module-path", modulePath.toString()) 356 .outdir(classes) 357 .files(findJavaFiles(moduleSrc)) 358 .run() 359 .writeAll(); 360 } 361} 362