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 tests for module resolution 27 * @library /tools/lib 28 * @modules 29 * jdk.compiler/com.sun.tools.javac.api 30 * jdk.compiler/com.sun.tools.javac.main 31 * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase 32 * @run main QueryBeforeEnter 33 */ 34 35 import java.io.File; 36 import java.io.OutputStream; 37 import java.nio.file.*; 38 import java.util.Arrays; 39 import java.util.Set; 40 41 import javax.annotation.processing.AbstractProcessor; 42 import javax.annotation.processing.RoundEnvironment; 43 import javax.annotation.processing.SupportedAnnotationTypes; 44 import javax.annotation.processing.SupportedSourceVersion; 45 import javax.lang.model.SourceVersion; 46 import javax.lang.model.element.TypeElement; 47 import javax.tools.JavaCompiler; 48 import javax.tools.StandardJavaFileManager; 49 import javax.tools.ToolProvider; 50 51 // import com.sun.source.util.JavacTask; 52 import com.sun.source.util.Plugin; 53 import com.sun.source.util.TaskEvent; 54 import com.sun.source.util.TaskListener; 55 import com.sun.tools.javac.Main; 56 57 import toolbox.JavacTask; 58 import toolbox.Task; 59 import toolbox.ToolBox; 60 61 public class QueryBeforeEnter extends ModuleTestBase { main(String... args)62 public static void main(String... args) throws Exception { 63 QueryBeforeEnter t = new QueryBeforeEnter(); 64 t.runTests(); 65 } 66 67 @Test testEmpty(Path base)68 public void testEmpty(Path base) throws Exception { 69 JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); 70 com.sun.source.util.JavacTask task = 71 (com.sun.source.util.JavacTask) javaCompiler.getTask(null, null, null, null, null, null); 72 TypeElement jlString = task.getElements().getTypeElement("java.lang.String"); 73 74 assertNotNull(jlString); 75 } 76 77 @Test testUnnamed(Path base)78 public void testUnnamed(Path base) throws Exception { 79 Path moduleSrc = base.resolve("module-src"); 80 Path m1 = moduleSrc.resolve("m1x"); 81 82 tb.writeJavaFiles(m1, 83 "module m1x { exports m1x; }", 84 "package m1x; public class M1 {}"); 85 86 Path m2 = moduleSrc.resolve("m2x"); 87 88 tb.writeJavaFiles(m2, 89 "module m2x { exports m2x; }", 90 "package m2x; public class M2 {}"); 91 92 Path modulePath = base.resolve("module-path"); 93 94 Files.createDirectories(modulePath); 95 96 new JavacTask(tb) 97 .options("--module-source-path", moduleSrc.toString()) 98 .outdir(modulePath) 99 .files(findJavaFiles(moduleSrc)) 100 .run() 101 .writeAll(); 102 103 Path cpSrc = base.resolve("cp-src"); 104 105 tb.writeJavaFiles(cpSrc, 106 "package cp; public class CP {}"); 107 108 Path cp = base.resolve("cp"); 109 110 Files.createDirectories(cp); 111 112 new JavacTask(tb) 113 .outdir(cp) 114 .files(findJavaFiles(cpSrc)) 115 .run() 116 .writeAll(); 117 118 Path src = base.resolve("src"); 119 120 tb.writeJavaFiles(src, 121 "package test; public class Test1 {}", 122 "package test; public class Test2 {}"); 123 124 Path out = base.resolve("out"); 125 126 Files.createDirectories(out); 127 128 JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); 129 try (StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) { 130 com.sun.source.util.JavacTask task = 131 (com.sun.source.util.JavacTask) javaCompiler.getTask(null, 132 null, 133 d -> { throw new IllegalStateException(d.toString()); }, 134 Arrays.asList("--module-path", modulePath.toString(), 135 "--class-path", cp.toString(), 136 "-sourcepath", src.toString()), 137 null, 138 fm.getJavaFileObjects(src.resolve("test").resolve("Test2.java"))); 139 assertNotNull(task.getElements().getTypeElement("java.lang.String")); 140 assertNotNull(task.getElements().getTypeElement("javax.tools.ToolProvider")); 141 assertNull(task.getElements().getTypeElement("m1x.M1")); 142 assertNull(task.getElements().getTypeElement("m2x.M2")); 143 assertNotNull(task.getElements().getTypeElement("cp.CP")); 144 assertNotNull(task.getElements().getTypeElement("test.Test1")); 145 assertNotNull(task.getElements().getTypeElement("test.Test2")); 146 assertNotNull(task.getElements().getModuleElement("java.base")); 147 assertNotNull(task.getElements().getModuleElement("java.compiler")); 148 assertNull(task.getElements().getModuleElement("m1x")); 149 assertNull(task.getElements().getModuleElement("m2x")); 150 } 151 } 152 153 @Test testSingleNamed(Path base)154 public void testSingleNamed(Path base) throws Exception { 155 Path moduleSrc = base.resolve("module-src"); 156 Path m1 = moduleSrc.resolve("m1x"); 157 158 tb.writeJavaFiles(m1, 159 "module m1x { exports m1x; }", 160 "package m1x; public class M1 {}"); 161 162 Path m2 = moduleSrc.resolve("m2x"); 163 164 tb.writeJavaFiles(m2, 165 "module m2x { exports m2x; }", 166 "package m2x; public class M2 {}"); 167 168 Path modulePath = base.resolve("module-path"); 169 170 Files.createDirectories(modulePath); 171 172 new JavacTask(tb) 173 .options("--module-source-path", moduleSrc.toString()) 174 .outdir(modulePath) 175 .files(findJavaFiles(moduleSrc)) 176 .run() 177 .writeAll(); 178 179 Path cpSrc = base.resolve("cp-src"); 180 181 tb.writeJavaFiles(cpSrc, 182 "package cp; public class CP {}"); 183 184 Path cp = base.resolve("cp"); 185 186 Files.createDirectories(cp); 187 188 new JavacTask(tb) 189 .outdir(cp) 190 .files(findJavaFiles(cpSrc)) 191 .run() 192 .writeAll(); 193 194 Path src = base.resolve("src"); 195 196 tb.writeJavaFiles(src, 197 "module test { requires java.base; requires m1x; } ", 198 "package test; public class Test {}"); 199 200 Path out = base.resolve("out"); 201 202 Files.createDirectories(out); 203 204 JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); 205 try (StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) { 206 com.sun.source.util.JavacTask task = 207 (com.sun.source.util.JavacTask) javaCompiler.getTask(null, 208 null, 209 d -> { throw new IllegalStateException(d.toString()); }, 210 Arrays.asList("--module-path", modulePath.toString(), 211 "--class-path", cp.toString(), 212 "-sourcepath", src.toString()), 213 null, 214 fm.getJavaFileObjects(findJavaFiles(src))); 215 assertNotNull(task.getElements().getTypeElement("java.lang.String")); 216 assertNull(task.getElements().getTypeElement("javax.tools.ToolProvider")); 217 assertNotNull(task.getElements().getTypeElement("m1x.M1")); 218 assertNull(task.getElements().getTypeElement("m2x.M2")); 219 assertNotNull(task.getElements().getTypeElement("test.Test")); 220 assertNotNull(task.getElements().getModuleElement("java.base")); 221 assertNull(task.getElements().getModuleElement("java.compiler")); 222 assertNotNull(task.getElements().getModuleElement("m1x")); 223 assertNull(task.getElements().getModuleElement("m2x")); 224 assertNotNull(task.getElements().getModuleElement("test")); 225 } 226 } 227 228 @Test testMultiModule(Path base)229 public void testMultiModule(Path base) throws Exception { 230 Path modulePathSrc = base.resolve("module-path-src"); 231 Path m1 = modulePathSrc.resolve("m1x"); 232 233 tb.writeJavaFiles(m1, 234 "module m1x { exports m1x; }", 235 "package m1x; public class M1 {}"); 236 237 Path m2 = modulePathSrc.resolve("m2x"); 238 239 tb.writeJavaFiles(m2, 240 "module m2x { exports m2x; }", 241 "package m2x; public class M2 {}"); 242 243 Path modulePath = base.resolve("module-path"); 244 245 Files.createDirectories(modulePath); 246 247 new JavacTask(tb) 248 .options("--module-source-path", modulePathSrc.toString()) 249 .outdir(modulePath) 250 .files(findJavaFiles(modulePathSrc)) 251 .run() 252 .writeAll(); 253 254 Path cpSrc = base.resolve("cp-src"); 255 256 tb.writeJavaFiles(cpSrc, 257 "package cp; public class CP {}"); 258 259 Path cp = base.resolve("cp"); 260 261 Files.createDirectories(cp); 262 263 new JavacTask(tb) 264 .outdir(cp) 265 .files(findJavaFiles(cpSrc)) 266 .run() 267 .writeAll(); 268 269 Path moduleSrc = base.resolve("module-src"); 270 Path m3 = moduleSrc.resolve("m3x"); 271 272 tb.writeJavaFiles(m3, 273 "module m3x { requires m1x; exports m3x; }", 274 "package m3x; public class M3 { }"); 275 276 Path m4 = moduleSrc.resolve("m4x"); 277 278 tb.writeJavaFiles(m4, 279 "module m4x { exports m4x; }", 280 "package m4x; public class M4 {}"); 281 282 Path out = base.resolve("out"); 283 284 Files.createDirectories(out); 285 286 JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); 287 try (StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) { 288 com.sun.source.util.JavacTask task = 289 (com.sun.source.util.JavacTask) javaCompiler.getTask(null, 290 null, 291 d -> { throw new IllegalStateException(d.toString()); }, 292 Arrays.asList("--module-path", modulePath.toString(), 293 "--class-path", cp.toString(), 294 "--module-source-path", moduleSrc.toString(), 295 "-d", out.toString()), 296 null, 297 fm.getJavaFileObjects(findJavaFiles(moduleSrc))); 298 assertNotNull(task.getElements().getTypeElement("java.lang.String")); 299 assertNull(task.getElements().getTypeElement("javax.tools.ToolProvider")); 300 assertNotNull(task.getElements().getTypeElement("m1x.M1")); 301 assertNull(task.getElements().getTypeElement("m2x.M2")); 302 assertNotNull(task.getElements().getTypeElement("m3x.M3")); 303 assertNotNull(task.getElements().getTypeElement("m4x.M4")); 304 assertNotNull(task.getElements().getModuleElement("java.base")); 305 assertNull(task.getElements().getModuleElement("java.compiler")); 306 assertNotNull(task.getElements().getModuleElement("m1x")); 307 assertNull(task.getElements().getModuleElement("m2x")); 308 assertNotNull(task.getElements().getModuleElement("m3x")); 309 assertNotNull(task.getElements().getModuleElement("m4x")); 310 } 311 } 312 313 @Test testTooSoon(Path base)314 public void testTooSoon(Path base) throws Exception { 315 Path src = base.resolve("src"); 316 317 tb.writeJavaFiles(src, 318 "package test; public class Test {}"); 319 320 Path out = base.resolve("out"); 321 322 Files.createDirectories(out); 323 324 Path reg = base.resolve("reg"); 325 Path regFile = reg.resolve("META-INF").resolve("services").resolve(Plugin.class.getName()); 326 327 Files.createDirectories(regFile.getParent()); 328 329 try (OutputStream regOut = Files.newOutputStream(regFile)) { 330 regOut.write(PluginImpl.class.getName().getBytes()); 331 } 332 333 String processorPath = System.getProperty("test.class.path") + File.pathSeparator + reg.toString(); 334 335 JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); 336 Path testSource = src.resolve("test").resolve("Test.java"); 337 try (StandardJavaFileManager fm = javaCompiler.getStandardFileManager(null, null, null)) { 338 com.sun.source.util.JavacTask task = 339 (com.sun.source.util.JavacTask) javaCompiler.getTask(null, 340 null, 341 d -> { throw new IllegalStateException(d.toString()); }, 342 Arrays.asList("--processor-path", processorPath, 343 "-processor", AP.class.getName(), 344 "-Xplugin:test"), 345 null, 346 fm.getJavaFileObjects(testSource)); 347 task.call(); 348 } 349 350 Main.compile(new String[] {"--processor-path", processorPath, 351 "-Xplugin:test", 352 testSource.toString()}); 353 } 354 355 public static class PluginImpl implements Plugin { 356 357 @Override getName()358 public String getName() { 359 return "test"; 360 } 361 362 @Override init(com.sun.source.util.JavacTask task, String... args)363 public void init(com.sun.source.util.JavacTask task, String... args) { 364 task.addTaskListener(new TaskListener() { 365 boolean wasEntered; 366 @Override 367 public void started(TaskEvent e) { 368 switch (e.getKind()) { 369 case COMPILATION: case PARSE: 370 shouldFail(e.getKind()); 371 break; 372 case ANNOTATION_PROCESSING: case ENTER: 373 if (wasEntered) { 374 shouldPass(e.getKind()); 375 } else { 376 shouldFail(e.getKind()); 377 } 378 break; 379 default: 380 shouldPass(e.getKind()); 381 break; 382 } 383 } 384 @Override 385 public void finished(TaskEvent e) { 386 switch (e.getKind()) { 387 case PARSE: 388 shouldFail(e.getKind()); 389 break; 390 case ENTER: 391 wasEntered = true; 392 //fall-through: 393 default: 394 shouldPass(e.getKind()); 395 break; 396 } 397 } 398 private void shouldFail(TaskEvent.Kind kind) { 399 try { 400 task.getElements().getTypeElement("java.lang.String"); 401 throw new AssertionError("Expected exception not observed; kind=" + kind.name()); 402 } catch (IllegalStateException ex) { 403 //correct 404 } 405 } 406 private void shouldPass(TaskEvent.Kind kind) { 407 assertNotNull(task.getElements().getTypeElement("java.lang.String")); 408 } 409 }); 410 411 } 412 413 } 414 415 @SupportedAnnotationTypes("*") 416 public static final class AP extends AbstractProcessor { 417 418 @Override process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)419 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 420 return false; 421 } 422 423 @Override getSupportedSourceVersion()424 public SourceVersion getSupportedSourceVersion() { 425 return SourceVersion.latest(); 426 } 427 428 } 429 assertNotNull(Object actual)430 private static void assertNotNull(Object actual) { 431 if (actual == null) { 432 throw new AssertionError("unexpected null!"); 433 } 434 } 435 assertNull(Object actual)436 private static void assertNull(Object actual) { 437 if (actual != null) { 438 throw new AssertionError("unexpected non null!"); 439 } 440 } 441 442 } 443