64 import com.sun.tools.javac.code.Symtab;
65 import com.sun.tools.javac.model.JavacElements;
66 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
67 import com.sun.tools.javac.util.Context;
68
69 import toolbox.JarTask;
70 import toolbox.JavacTask;
71 import toolbox.JavaTask;
72 import toolbox.Task;
73
74 public class AddLimitMods extends ModuleTestBase {
75
76 public static void main(String... args) throws Exception {
77 AddLimitMods t = new AddLimitMods();
78 t.runTests();
79 }
80
81 @Test
82 public void testManual(Path base) throws Exception {
83 Path moduleSrc = base.resolve("module-src");
84 Path m1 = moduleSrc.resolve("m1");
85
86 tb.writeJavaFiles(m1,
87 "module m1 { requires m2; requires m3; }");
88
89 Path m2 = moduleSrc.resolve("m2");
90
91 tb.writeJavaFiles(m2,
92 "module m2 { requires m3; exports m2; }",
93 "package m2; public class M2 {}");
94
95 Path m3 = moduleSrc.resolve("m3");
96
97 tb.writeJavaFiles(m3,
98 "module m3 { exports m3; }",
99 "package m3; public class M3 {}");
100
101 Path modulePath = base.resolve("module-path");
102
103 Files.createDirectories(modulePath);
104
105 new JavacTask(tb)
106 .options("--module-source-path", moduleSrc.toString())
107 .outdir(modulePath)
108 .files(findJavaFiles(m3))
109 .run()
110 .writeAll();
111
112 new JavacTask(tb)
113 .options("--module-source-path", moduleSrc.toString())
114 .outdir(modulePath)
115 .files(findJavaFiles(m2))
116 .run()
117 .writeAll();
118
119 //real test
120 new JavacTask(tb)
121 .options("--module-path", modulePath.toString(),
122 "--should-stop:ifNoError=FLOW",
123 "--limit-modules", "java.base")
124 .outdir(modulePath)
125 .files(findJavaFiles(m1))
126 .run(Task.Expect.FAIL)
127 .writeAll();
128
129 new JavacTask(tb)
130 .options("--module-path", modulePath.toString(),
131 "--should-stop:ifNoError=FLOW",
132 "--limit-modules", "java.base",
133 "--add-modules", "m2")
134 .outdir(modulePath)
135 .files(findJavaFiles(m1))
136 .run(Task.Expect.FAIL)
137 .writeAll();
138
139 new JavacTask(tb)
140 .options("--module-path", modulePath.toString(),
141 "--should-stop:ifNoError=FLOW",
142 "--limit-modules", "java.base",
143 "--add-modules", "m2,m3")
144 .outdir(modulePath)
145 .files(findJavaFiles(m1))
146 .run()
147 .writeAll();
148
149 new JavacTask(tb)
150 .options("--module-path", modulePath.toString(),
151 "--should-stop:ifNoError=FLOW",
152 "--limit-modules", "m2")
153 .outdir(modulePath)
154 .files(findJavaFiles(m1))
155 .run()
156 .writeAll();
157
158 new JavacTask(tb)
159 .options("--module-path", modulePath.toString(),
160 "--should-stop:ifNoError=FLOW",
161 "--limit-modules", "m3")
162 .outdir(modulePath)
163 .files(findJavaFiles(m1))
164 .run(Task.Expect.FAIL)
165 .writeAll();
166
167 new JavacTask(tb)
168 .options("--module-path", modulePath.toString(),
169 "--should-stop:ifNoError=FLOW",
170 "--limit-modules", "m3",
171 "--add-modules", "m2")
172 .outdir(modulePath)
173 .files(findJavaFiles(m1))
174 .run()
175 .writeAll();
176 }
177
178 @Test
179 public void testObservableForUnnamed(Path base) throws Exception {
180 Path src = base.resolve("src");
181
182 tb.writeJavaFiles(src,
183 "package test;\n" +
184 "@javax.annotation.Generated(\"test\")\n" +
185 "public class Test {\n" +
186 " com.sun.tools.javac.Main m;\n" +
187 " javax.xml.bind.JAXBException e;\n" +
188 "}\n");
189
190 Path out = base.resolve("out");
191
216
217 private static final List<Entry<String[], String>> variants = Arrays.asList(
218 new SimpleEntry<String[], String>(new String[] {},
219 "Test.java:2:18: compiler.err.doesnt.exist: javax.annotation\n"
220 + "Test.java:5:19: compiler.err.doesnt.exist: javax.xml.bind\n"
221 + "2 errors\n"),
222 new SimpleEntry<String[], String>(new String[] {"--add-modules", "java.annotations.common,java.xml.bind"},
223 null),
224 new SimpleEntry<String[], String>(new String[] {"--limit-modules", "java.xml.ws,jdk.compiler"},
225 null),
226 new SimpleEntry<String[], String>(new String[] {"--add-modules", "ALL-SYSTEM"},
227 null)
228 );
229
230 @Test
231 public void testAllModulePath(Path base) throws Exception {
232 if (Files.isDirectory(base))
233 tb.cleanDirectory(base);
234
235 Path moduleSrc = base.resolve("module-src");
236 Path m1 = moduleSrc.resolve("m1");
237
238 tb.writeJavaFiles(m1,
239 "module m1 { exports api; }",
240 "package api; public class Api { }");
241
242 Path modulePath = base.resolve("module-path");
243
244 Files.createDirectories(modulePath);
245
246 new JavacTask(tb)
247 .options("--module-source-path", moduleSrc.toString())
248 .outdir(modulePath)
249 .files(findJavaFiles(moduleSrc))
250 .run()
251 .writeAll();
252
253 Path cpSrc = base.resolve("cp-src");
254 tb.writeJavaFiles(cpSrc, "package test; public class Test { api.Api api; }");
255
256 Path cpOut = base.resolve("cp-out");
257
258 Files.createDirectories(cpOut);
259
302 .getOutputLines(Task.OutputKind.DIRECT);
303
304 if (!Objects.equals(actual, expected)) {
305 throw new IllegalStateException("incorrect errors; actual=" + actual + "; expected=" + expected);
306 }
307
308 actual = new JavacTask(tb, Task.Mode.CMDLINE)
309 .options("-source", "8", "-target", "8",
310 "-XDrawDiagnostics",
311 "--add-modules", "ALL-MODULE-PATH")
312 .outdir(cpOut)
313 .files(findJavaFiles(cpSrc))
314 .run(Task.Expect.FAIL)
315 .writeAll()
316 .getOutputLines(Task.OutputKind.DIRECT);
317
318 if (!actual.contains("javac: option --add-modules not allowed with target 1.8")) {
319 throw new IllegalStateException("incorrect errors; actual=" + actual);
320 }
321
322 tb.writeJavaFiles(cpSrc, "module m1 {}");
323
324 actual = new JavacTask(tb)
325 .options("-XDrawDiagnostics",
326 "--add-modules", "ALL-MODULE-PATH")
327 .outdir(cpOut)
328 .files(findJavaFiles(cpSrc))
329 .run(Task.Expect.FAIL)
330 .writeAll()
331 .getOutputLines(Task.OutputKind.DIRECT);
332
333 if (!Objects.equals(actual, expected)) {
334 throw new IllegalStateException("incorrect errors; actual=" + actual + "; expected=" + expected);
335 }
336 }
337
338 @Test
339 public void testRuntime2Compile(Path base) throws Exception {
340 Path classpathSrc = base.resolve("classpath-src");
341 Path classpathOut = base.resolve("classpath-out");
342
365 new JavacTask(tb)
366 .outdir(automaticOut)
367 .files(findJavaFiles(automaticSrc))
368 .run()
369 .writeAll()
370 .getOutput(Task.OutputKind.DIRECT);
371
372 Path modulePath = base.resolve("module-path");
373
374 Files.createDirectories(modulePath);
375
376 Path automaticJar = modulePath.resolve("automatic.jar");
377
378 System.err.println("Creating automatic.jar:");
379 new JarTask(tb, automaticJar)
380 .baseDir(automaticOut)
381 .files("automatic/Automatic.class")
382 .run();
383
384 Path moduleSrc = base.resolve("module-src");
385 Path m1 = moduleSrc.resolve("m1");
386
387 tb.writeJavaFiles(m1,
388 "module m1 { exports api; }",
389 "package api; public class Api { public void test() { } }");
390
391 System.err.println("Compiling module-src files:");
392 new JavacTask(tb)
393 .options("--module-source-path", moduleSrc.toString())
394 .outdir(modulePath)
395 .files(findJavaFiles(moduleSrc))
396 .run()
397 .writeAll()
398 .getOutput(Task.OutputKind.DIRECT);
399
400 int index = 0;
401
402 for (String moduleInfo : MODULE_INFO_VARIANTS) {
403 for (String[] options : OPTIONS_VARIANTS) {
404 index++;
405
406 System.err.println("Running check: " + moduleInfo + "; " + Arrays.asList(options));
407
408 Path m2Runtime = base.resolve(index + "-runtime").resolve("m2");
409 Path out = base.resolve(index + "-runtime").resolve("out").resolve("m2");
410
411 Files.createDirectories(out);
412
413 StringBuilder testClassNamed = new StringBuilder();
414
415 testClassNamed.append("package test;\n" +
416 "public class Test {\n" +
417 " public static void main(String... args) throws Exception {\n");
418
419 for (Entry<String, String> e : MODULES_TO_CHECK_TO_SAMPLE_CLASS.entrySet()) {
420 testClassNamed.append(" System.err.println(\"visible:" + e.getKey() + ":\" + java.lang.reflect.Layer.boot().findModule(\"" + e.getKey() + "\").isPresent());\n");
421 }
422
423 testClassNamed.append(" Class<?> cp = Class.forName(Test.class.getClassLoader().getUnnamedModule(), \"cp.CP\");\n");
424 testClassNamed.append(" cp.getDeclaredMethod(\"runMe\").invoke(null);\n");
425
426 testClassNamed.append(" Class<?> automatic = Class.forName(java.lang.reflect.Layer.boot().findModule(\"automatic\").get(), \"automatic.Automatic\");\n");
427 testClassNamed.append(" automatic.getDeclaredMethod(\"runMe\").invoke(null);\n");
428
429 testClassNamed.append(" }\n" +
430 "}");
431
432 tb.writeJavaFiles(m2Runtime, moduleInfo, testClassNamed.toString());
433
434 System.err.println("Compiling " + m2Runtime + " files:");
435 new JavacTask(tb)
436 .options("--module-path", modulePath.toString())
437 .outdir(out)
438 .files(findJavaFiles(m2Runtime))
439 .run()
440 .writeAll();
441
442 boolean success;
443 String output;
444
445 try {
446 System.err.println("Running m2/test.Test:");
447 output = new JavaTask(tb)
448 .vmOptions(augmentOptions(options,
449 Collections.emptyList(),
450 "--module-path", modulePath.toString() + File.pathSeparator + out.getParent().toString(),
451 "--class-path", classpathOut.toString(),
452 "--add-reads", "m2=ALL-UNNAMED,automatic",
453 "-m", "m2/test.Test"))
454 .run()
455 .writeAll()
456 .getOutput(Task.OutputKind.STDERR);
457
458 success = true;
459 } catch (Task.TaskError err) {
460 success = false;
461 output = "";
462 }
463
464 Path m2 = base.resolve(String.valueOf(index)).resolve("m2");
465
466 tb.writeJavaFiles(m2,
467 moduleInfo,
468 "package test;\n" +
469 "public class Test {}\n");
470
471 List<String> auxOptions = success ? Arrays.asList(
472 "--processor-path", System.getProperty("test.class.path"),
473 "-processor", CheckVisibleModule.class.getName(),
474 "-Aoutput=" + output,
475 "-XDaccessInternalAPI=true"
476 ) : Collections.emptyList();
477
478 System.err.println("Compiling/processing m2 files:");
479 new JavacTask(tb)
480 .options(augmentOptions(options,
481 auxOptions,
482 "--module-path", modulePath.toString(),
483 "--class-path", classpathOut.toString(),
484 "--should-stop:ifNoError=FLOW"))
485 .outdir(modulePath)
486 .files(findJavaFiles(m2))
487 .run(success ? Task.Expect.SUCCESS : Task.Expect.FAIL)
488 .writeAll();
489 }
490 }
491 }
492
493 private String generateCheckAccessibleClass(String fqn) {
494 String packageName = fqn.substring(0, fqn.lastIndexOf('.'));
495 String simpleName = fqn.substring(fqn.lastIndexOf('.') + 1);
496 StringBuilder checkClassesAccessible = new StringBuilder();
497 checkClassesAccessible.append("package " + packageName + ";" +
498 "public class " + simpleName + " {" +
499 " public static void runMe() throws Exception {");
500 for (Entry<String, String> e : MODULES_TO_CHECK_TO_SAMPLE_CLASS.entrySet()) {
501 checkClassesAccessible.append("try {");
502 checkClassesAccessible.append("Class.forName(\"" + e.getValue() + "\").newInstance();");
503 checkClassesAccessible.append("System.err.println(\"" + fqn + ":" + e.getKey() + ":true\");");
504 checkClassesAccessible.append("} catch (Exception ex) {");
505 checkClassesAccessible.append("System.err.println(\"" + fqn + ":" + e.getKey() + ":false\");");
506 checkClassesAccessible.append("}");
507 }
508
509 checkClassesAccessible.append(" }\n" +
510 "}");
511
512 return checkClassesAccessible.toString();
513 }
514
515 private static final Map<String, String> MODULES_TO_CHECK_TO_SAMPLE_CLASS = new LinkedHashMap<>();
516
517 static {
518 MODULES_TO_CHECK_TO_SAMPLE_CLASS.put("m1", "api.Api");
519 MODULES_TO_CHECK_TO_SAMPLE_CLASS.put("m2", "test.Test");
520 MODULES_TO_CHECK_TO_SAMPLE_CLASS.put("java.base", "java.lang.Object");
521 };
522
523 @SupportedAnnotationTypes("*")
524 @SupportedOptions("output")
525 public static final class CheckVisibleModule extends AbstractProcessor {
526
527 @Override
528 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
529 String expected = processingEnv.getOptions().get("output");
530 Set<String> expectedElements = new HashSet<>(Arrays.asList(expected.split(System.getProperty("line.separator"))));
531 Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
532 Symtab syms = Symtab.instance(context);
533
534 for (Entry<String, String> e : MODULES_TO_CHECK_TO_SAMPLE_CLASS.entrySet()) {
535 String module = e.getKey();
536 ModuleElement mod = processingEnv.getElementUtils().getModuleElement(module);
537 String visible = "visible:" + module + ":" + (mod != null);
538
539 if (!expectedElements.contains(visible)) {
561 }
562
563 @Override
564 public SourceVersion getSupportedSourceVersion() {
565 return SourceVersion.latest();
566 }
567
568 }
569
570 public String[] augmentOptions(String[] options, List<String> auxOptions, String... baseOptions) {
571 List<String> all = new ArrayList<>();
572
573 all.addAll(Arrays.asList(options));
574 all.addAll(Arrays.asList(baseOptions));
575 all.addAll(auxOptions);
576
577 return all.toArray(new String[0]);
578 }
579
580 private static final String[] MODULE_INFO_VARIANTS = {
581 "module m2 { exports test; }",
582 "module m2 { requires m1; exports test; }"
583 };
584
585 private static final String[][] OPTIONS_VARIANTS = {
586 {"--add-modules", "automatic"},
587 {"--add-modules", "m1,automatic"},
588 {"--add-modules", "jdk.compiler,automatic"},
589 {"--add-modules", "m1,jdk.compiler,automatic"},
590 {"--add-modules", "ALL-SYSTEM,automatic"},
591 {"--limit-modules", "java.base", "--add-modules", "automatic"},
592 {"--limit-modules", "java.base", "--add-modules", "ALL-SYSTEM,automatic"},
593 {"--limit-modules", "m2", "--add-modules", "automatic"},
594 {"--limit-modules", "jdk.compiler", "--add-modules", "automatic"},
595 };
596 }
|
64 import com.sun.tools.javac.code.Symtab;
65 import com.sun.tools.javac.model.JavacElements;
66 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
67 import com.sun.tools.javac.util.Context;
68
69 import toolbox.JarTask;
70 import toolbox.JavacTask;
71 import toolbox.JavaTask;
72 import toolbox.Task;
73
74 public class AddLimitMods extends ModuleTestBase {
75
76 public static void main(String... args) throws Exception {
77 AddLimitMods t = new AddLimitMods();
78 t.runTests();
79 }
80
81 @Test
82 public void testManual(Path base) throws Exception {
83 Path moduleSrc = base.resolve("module-src");
84 Path m1 = moduleSrc.resolve("m1x");
85
86 tb.writeJavaFiles(m1,
87 "module m1x { requires m2x; requires m3x; }");
88
89 Path m2 = moduleSrc.resolve("m2x");
90
91 tb.writeJavaFiles(m2,
92 "module m2x { requires m3x; exports m2x; }",
93 "package m2x; public class M2 {}");
94
95 Path m3 = moduleSrc.resolve("m3x");
96
97 tb.writeJavaFiles(m3,
98 "module m3x { exports m3x; }",
99 "package m3x; public class M3 {}");
100
101 Path modulePath = base.resolve("module-path");
102
103 Files.createDirectories(modulePath);
104
105 new JavacTask(tb)
106 .options("--module-source-path", moduleSrc.toString())
107 .outdir(modulePath)
108 .files(findJavaFiles(m3))
109 .run()
110 .writeAll();
111
112 new JavacTask(tb)
113 .options("--module-source-path", moduleSrc.toString())
114 .outdir(modulePath)
115 .files(findJavaFiles(m2))
116 .run()
117 .writeAll();
118
119 //real test
120 new JavacTask(tb)
121 .options("--module-path", modulePath.toString(),
122 "--should-stop:ifNoError=FLOW",
123 "--limit-modules", "java.base")
124 .outdir(modulePath)
125 .files(findJavaFiles(m1))
126 .run(Task.Expect.FAIL)
127 .writeAll();
128
129 new JavacTask(tb)
130 .options("--module-path", modulePath.toString(),
131 "--should-stop:ifNoError=FLOW",
132 "--limit-modules", "java.base",
133 "--add-modules", "m2x")
134 .outdir(modulePath)
135 .files(findJavaFiles(m1))
136 .run(Task.Expect.FAIL)
137 .writeAll();
138
139 new JavacTask(tb)
140 .options("--module-path", modulePath.toString(),
141 "--should-stop:ifNoError=FLOW",
142 "--limit-modules", "java.base",
143 "--add-modules", "m2x,m3x")
144 .outdir(modulePath)
145 .files(findJavaFiles(m1))
146 .run()
147 .writeAll();
148
149 new JavacTask(tb)
150 .options("--module-path", modulePath.toString(),
151 "--should-stop:ifNoError=FLOW",
152 "--limit-modules", "m2x")
153 .outdir(modulePath)
154 .files(findJavaFiles(m1))
155 .run()
156 .writeAll();
157
158 new JavacTask(tb)
159 .options("--module-path", modulePath.toString(),
160 "--should-stop:ifNoError=FLOW",
161 "--limit-modules", "m3x")
162 .outdir(modulePath)
163 .files(findJavaFiles(m1))
164 .run(Task.Expect.FAIL)
165 .writeAll();
166
167 new JavacTask(tb)
168 .options("--module-path", modulePath.toString(),
169 "--should-stop:ifNoError=FLOW",
170 "--limit-modules", "m3x",
171 "--add-modules", "m2x")
172 .outdir(modulePath)
173 .files(findJavaFiles(m1))
174 .run()
175 .writeAll();
176 }
177
178 @Test
179 public void testObservableForUnnamed(Path base) throws Exception {
180 Path src = base.resolve("src");
181
182 tb.writeJavaFiles(src,
183 "package test;\n" +
184 "@javax.annotation.Generated(\"test\")\n" +
185 "public class Test {\n" +
186 " com.sun.tools.javac.Main m;\n" +
187 " javax.xml.bind.JAXBException e;\n" +
188 "}\n");
189
190 Path out = base.resolve("out");
191
216
217 private static final List<Entry<String[], String>> variants = Arrays.asList(
218 new SimpleEntry<String[], String>(new String[] {},
219 "Test.java:2:18: compiler.err.doesnt.exist: javax.annotation\n"
220 + "Test.java:5:19: compiler.err.doesnt.exist: javax.xml.bind\n"
221 + "2 errors\n"),
222 new SimpleEntry<String[], String>(new String[] {"--add-modules", "java.annotations.common,java.xml.bind"},
223 null),
224 new SimpleEntry<String[], String>(new String[] {"--limit-modules", "java.xml.ws,jdk.compiler"},
225 null),
226 new SimpleEntry<String[], String>(new String[] {"--add-modules", "ALL-SYSTEM"},
227 null)
228 );
229
230 @Test
231 public void testAllModulePath(Path base) throws Exception {
232 if (Files.isDirectory(base))
233 tb.cleanDirectory(base);
234
235 Path moduleSrc = base.resolve("module-src");
236 Path m1 = moduleSrc.resolve("m1x");
237
238 tb.writeJavaFiles(m1,
239 "module m1x { exports api; }",
240 "package api; public class Api { }");
241
242 Path modulePath = base.resolve("module-path");
243
244 Files.createDirectories(modulePath);
245
246 new JavacTask(tb)
247 .options("--module-source-path", moduleSrc.toString())
248 .outdir(modulePath)
249 .files(findJavaFiles(moduleSrc))
250 .run()
251 .writeAll();
252
253 Path cpSrc = base.resolve("cp-src");
254 tb.writeJavaFiles(cpSrc, "package test; public class Test { api.Api api; }");
255
256 Path cpOut = base.resolve("cp-out");
257
258 Files.createDirectories(cpOut);
259
302 .getOutputLines(Task.OutputKind.DIRECT);
303
304 if (!Objects.equals(actual, expected)) {
305 throw new IllegalStateException("incorrect errors; actual=" + actual + "; expected=" + expected);
306 }
307
308 actual = new JavacTask(tb, Task.Mode.CMDLINE)
309 .options("-source", "8", "-target", "8",
310 "-XDrawDiagnostics",
311 "--add-modules", "ALL-MODULE-PATH")
312 .outdir(cpOut)
313 .files(findJavaFiles(cpSrc))
314 .run(Task.Expect.FAIL)
315 .writeAll()
316 .getOutputLines(Task.OutputKind.DIRECT);
317
318 if (!actual.contains("javac: option --add-modules not allowed with target 1.8")) {
319 throw new IllegalStateException("incorrect errors; actual=" + actual);
320 }
321
322 tb.writeJavaFiles(cpSrc, "module m1x {}");
323
324 actual = new JavacTask(tb)
325 .options("-XDrawDiagnostics",
326 "--add-modules", "ALL-MODULE-PATH")
327 .outdir(cpOut)
328 .files(findJavaFiles(cpSrc))
329 .run(Task.Expect.FAIL)
330 .writeAll()
331 .getOutputLines(Task.OutputKind.DIRECT);
332
333 if (!Objects.equals(actual, expected)) {
334 throw new IllegalStateException("incorrect errors; actual=" + actual + "; expected=" + expected);
335 }
336 }
337
338 @Test
339 public void testRuntime2Compile(Path base) throws Exception {
340 Path classpathSrc = base.resolve("classpath-src");
341 Path classpathOut = base.resolve("classpath-out");
342
365 new JavacTask(tb)
366 .outdir(automaticOut)
367 .files(findJavaFiles(automaticSrc))
368 .run()
369 .writeAll()
370 .getOutput(Task.OutputKind.DIRECT);
371
372 Path modulePath = base.resolve("module-path");
373
374 Files.createDirectories(modulePath);
375
376 Path automaticJar = modulePath.resolve("automatic.jar");
377
378 System.err.println("Creating automatic.jar:");
379 new JarTask(tb, automaticJar)
380 .baseDir(automaticOut)
381 .files("automatic/Automatic.class")
382 .run();
383
384 Path moduleSrc = base.resolve("module-src");
385 Path m1 = moduleSrc.resolve("m1x");
386
387 tb.writeJavaFiles(m1,
388 "module m1x { exports api; }",
389 "package api; public class Api { public void test() { } }");
390
391 System.err.println("Compiling module-src files:");
392 new JavacTask(tb)
393 .options("--module-source-path", moduleSrc.toString())
394 .outdir(modulePath)
395 .files(findJavaFiles(moduleSrc))
396 .run()
397 .writeAll()
398 .getOutput(Task.OutputKind.DIRECT);
399
400 int index = 0;
401
402 for (String moduleInfo : MODULE_INFO_VARIANTS) {
403 for (String[] options : OPTIONS_VARIANTS) {
404 index++;
405
406 System.err.println("Running check: " + moduleInfo + "; " + Arrays.asList(options));
407
408 Path m2Runtime = base.resolve(index + "-runtime").resolve("m2x");
409 Path out = base.resolve(index + "-runtime").resolve("out").resolve("m2x");
410
411 Files.createDirectories(out);
412
413 StringBuilder testClassNamed = new StringBuilder();
414
415 testClassNamed.append("package test;\n" +
416 "public class Test {\n" +
417 " public static void main(String... args) throws Exception {\n");
418
419 for (Entry<String, String> e : MODULES_TO_CHECK_TO_SAMPLE_CLASS.entrySet()) {
420 testClassNamed.append(" System.err.println(\"visible:" + e.getKey() + ":\" + java.lang.reflect.Layer.boot().findModule(\"" + e.getKey() + "\").isPresent());\n");
421 }
422
423 testClassNamed.append(" Class<?> cp = Class.forName(Test.class.getClassLoader().getUnnamedModule(), \"cp.CP\");\n");
424 testClassNamed.append(" cp.getDeclaredMethod(\"runMe\").invoke(null);\n");
425
426 testClassNamed.append(" Class<?> automatic = Class.forName(java.lang.reflect.Layer.boot().findModule(\"automatic\").get(), \"automatic.Automatic\");\n");
427 testClassNamed.append(" automatic.getDeclaredMethod(\"runMe\").invoke(null);\n");
428
429 testClassNamed.append(" }\n" +
430 "}");
431
432 tb.writeJavaFiles(m2Runtime, moduleInfo, testClassNamed.toString());
433
434 System.err.println("Compiling " + m2Runtime + " files:");
435 new JavacTask(tb)
436 .options("--module-path", modulePath.toString())
437 .outdir(out)
438 .files(findJavaFiles(m2Runtime))
439 .run()
440 .writeAll();
441
442 boolean success;
443 String output;
444
445 try {
446 System.err.println("Running m2x/test.Test:");
447 output = new JavaTask(tb)
448 .vmOptions(augmentOptions(options,
449 Collections.emptyList(),
450 "--module-path", modulePath.toString() + File.pathSeparator + out.getParent().toString(),
451 "--class-path", classpathOut.toString(),
452 "--add-reads", "m2x=ALL-UNNAMED,automatic",
453 "-m", "m2x/test.Test"))
454 .run()
455 .writeAll()
456 .getOutput(Task.OutputKind.STDERR);
457
458 success = true;
459 } catch (Task.TaskError err) {
460 success = false;
461 output = "";
462 }
463
464 Path m2 = base.resolve(String.valueOf(index)).resolve("m2x");
465
466 tb.writeJavaFiles(m2,
467 moduleInfo,
468 "package test;\n" +
469 "public class Test {}\n");
470
471 List<String> auxOptions = success ? Arrays.asList(
472 "--processor-path", System.getProperty("test.class.path"),
473 "-processor", CheckVisibleModule.class.getName(),
474 "-Aoutput=" + output,
475 "-XDaccessInternalAPI=true"
476 ) : Collections.emptyList();
477
478 System.err.println("Compiling/processing m2x files:");
479 new JavacTask(tb)
480 .options(augmentOptions(options,
481 auxOptions,
482 "--module-path", modulePath.toString(),
483 "--class-path", classpathOut.toString(),
484 "--should-stop:ifNoError=FLOW"))
485 .outdir(modulePath)
486 .files(findJavaFiles(m2))
487 .run(success ? Task.Expect.SUCCESS : Task.Expect.FAIL)
488 .writeAll();
489 }
490 }
491 }
492
493 private String generateCheckAccessibleClass(String fqn) {
494 String packageName = fqn.substring(0, fqn.lastIndexOf('.'));
495 String simpleName = fqn.substring(fqn.lastIndexOf('.') + 1);
496 StringBuilder checkClassesAccessible = new StringBuilder();
497 checkClassesAccessible.append("package " + packageName + ";" +
498 "public class " + simpleName + " {" +
499 " public static void runMe() throws Exception {");
500 for (Entry<String, String> e : MODULES_TO_CHECK_TO_SAMPLE_CLASS.entrySet()) {
501 checkClassesAccessible.append("try {");
502 checkClassesAccessible.append("Class.forName(\"" + e.getValue() + "\").newInstance();");
503 checkClassesAccessible.append("System.err.println(\"" + fqn + ":" + e.getKey() + ":true\");");
504 checkClassesAccessible.append("} catch (Exception ex) {");
505 checkClassesAccessible.append("System.err.println(\"" + fqn + ":" + e.getKey() + ":false\");");
506 checkClassesAccessible.append("}");
507 }
508
509 checkClassesAccessible.append(" }\n" +
510 "}");
511
512 return checkClassesAccessible.toString();
513 }
514
515 private static final Map<String, String> MODULES_TO_CHECK_TO_SAMPLE_CLASS = new LinkedHashMap<>();
516
517 static {
518 MODULES_TO_CHECK_TO_SAMPLE_CLASS.put("m1x", "api.Api");
519 MODULES_TO_CHECK_TO_SAMPLE_CLASS.put("m2x", "test.Test");
520 MODULES_TO_CHECK_TO_SAMPLE_CLASS.put("java.base", "java.lang.Object");
521 };
522
523 @SupportedAnnotationTypes("*")
524 @SupportedOptions("output")
525 public static final class CheckVisibleModule extends AbstractProcessor {
526
527 @Override
528 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
529 String expected = processingEnv.getOptions().get("output");
530 Set<String> expectedElements = new HashSet<>(Arrays.asList(expected.split(System.getProperty("line.separator"))));
531 Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
532 Symtab syms = Symtab.instance(context);
533
534 for (Entry<String, String> e : MODULES_TO_CHECK_TO_SAMPLE_CLASS.entrySet()) {
535 String module = e.getKey();
536 ModuleElement mod = processingEnv.getElementUtils().getModuleElement(module);
537 String visible = "visible:" + module + ":" + (mod != null);
538
539 if (!expectedElements.contains(visible)) {
561 }
562
563 @Override
564 public SourceVersion getSupportedSourceVersion() {
565 return SourceVersion.latest();
566 }
567
568 }
569
570 public String[] augmentOptions(String[] options, List<String> auxOptions, String... baseOptions) {
571 List<String> all = new ArrayList<>();
572
573 all.addAll(Arrays.asList(options));
574 all.addAll(Arrays.asList(baseOptions));
575 all.addAll(auxOptions);
576
577 return all.toArray(new String[0]);
578 }
579
580 private static final String[] MODULE_INFO_VARIANTS = {
581 "module m2x { exports test; }",
582 "module m2x { requires m1x; exports test; }"
583 };
584
585 private static final String[][] OPTIONS_VARIANTS = {
586 {"--add-modules", "automatic"},
587 {"--add-modules", "m1x,automatic"},
588 {"--add-modules", "jdk.compiler,automatic"},
589 {"--add-modules", "m1x,jdk.compiler,automatic"},
590 {"--add-modules", "ALL-SYSTEM,automatic"},
591 {"--limit-modules", "java.base", "--add-modules", "automatic"},
592 {"--limit-modules", "java.base", "--add-modules", "ALL-SYSTEM,automatic"},
593 {"--limit-modules", "m2x", "--add-modules", "automatic"},
594 {"--limit-modules", "jdk.compiler", "--add-modules", "automatic"},
595 };
596 }
|