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