AddReadsTest.java revision 3573:c4a18ee691c4
1/* 2 * Copyright (c) 2015, 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 Test the --add-reads option 27 * @library /tools/lib 28 * @modules jdk.compiler/com.sun.tools.javac.api 29 * jdk.compiler/com.sun.tools.javac.main 30 * jdk.jdeps/com.sun.tools.javap 31 * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask toolbox.JavapTask ModuleTestBase 32 * @run main AddReadsTest 33 */ 34 35import java.nio.file.Files; 36import java.nio.file.Path; 37import java.util.Set; 38 39import javax.annotation.processing.AbstractProcessor; 40import javax.annotation.processing.RoundEnvironment; 41import javax.annotation.processing.SupportedAnnotationTypes; 42import javax.lang.model.SourceVersion; 43import javax.lang.model.element.ModuleElement; 44import javax.lang.model.element.ModuleElement.RequiresDirective; 45import javax.lang.model.element.TypeElement; 46import javax.lang.model.util.ElementFilter; 47 48import toolbox.JarTask; 49import toolbox.JavacTask; 50import toolbox.JavapTask; 51import toolbox.Task; 52import toolbox.ToolBox; 53 54public class AddReadsTest extends ModuleTestBase { 55 56 public static void main(String... args) throws Exception { 57 new AddReadsTest().runTests(); 58 } 59 60 @Test 61 public void testAddReads(Path base) throws Exception { 62 Path src = base.resolve("src"); 63 Path src_m1 = src.resolve("m1"); 64 tb.writeJavaFiles(src_m1, 65 "module m1 { exports api; }", 66 "package api; public class Api { }"); 67 Path src_m2 = src.resolve("m2"); 68 tb.writeJavaFiles(src_m2, 69 "module m2 { }", 70 "package test; public class Test extends api.Api { }"); 71 Path classes = base.resolve("classes"); 72 tb.createDirectories(classes); 73 74 String log = new JavacTask(tb) 75 .options("-XDrawDiagnostics", 76 "--module-source-path", src.toString()) 77 .outdir(classes) 78 .files(findJavaFiles(src)) 79 .run(Task.Expect.FAIL) 80 .writeAll() 81 .getOutput(Task.OutputKind.DIRECT); 82 83 if (!log.contains("Test.java:1:44: compiler.err.not.def.access.package.cant.access: api.Api, api")) 84 throw new Exception("expected output not found"); 85 86 //test add dependencies: 87 new JavacTask(tb) 88 .options("--add-reads", "m2=m1", 89 "--module-source-path", src.toString(), 90 "-processor", VerifyRequires.class.getName()) 91 .outdir(classes) 92 .files(findJavaFiles(src)) 93 .run() 94 .writeAll(); 95 96 String decompiled = new JavapTask(tb) 97 .options("-verbose", classes.resolve("m2").resolve("module-info.class").toString()) 98 .run() 99 .getOutput(Task.OutputKind.DIRECT); 100 101 if (decompiled.contains("m1")) { 102 throw new Exception("Incorrectly refers to m1 module."); 103 } 104 105 //cyclic dependencies OK when created through addReads: 106 new JavacTask(tb) 107 .options("--add-reads", "m2=m1,m1=m2", 108 "--module-source-path", src.toString()) 109 .outdir(classes) 110 .files(findJavaFiles(src)) 111 .run() 112 .writeAll(); 113 114 tb.writeJavaFiles(src_m2, 115 "module m2 { requires m1; }"); 116 117 new JavacTask(tb) 118 .options("--add-reads", "m1=m2", 119 "--module-source-path", src.toString()) 120 .outdir(classes) 121 .files(findJavaFiles(src)) 122 .run() 123 .writeAll(); 124 } 125 126 @SupportedAnnotationTypes("*") 127 public static final class VerifyRequires extends AbstractProcessor { 128 129 @Override 130 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 131 ModuleElement m2Module = processingEnv.getElementUtils().getModuleElement("m2"); 132 if (m2Module == null) { 133 throw new AssertionError("Cannot find the m2 module!"); 134 } 135 boolean foundM1 = false; 136 for (RequiresDirective rd : ElementFilter.requiresIn(m2Module.getDirectives())) { 137 foundM1 |= rd.getDependency().getSimpleName().contentEquals("m1"); 138 } 139 if (!foundM1) { 140 throw new AssertionError("Cannot find the dependency on m1 module!"); 141 } 142 return false; 143 } 144 145 @Override 146 public SourceVersion getSupportedSourceVersion() { 147 return SourceVersion.latest(); 148 } 149 150 } 151 152 @Test 153 public void testAddReadsUnnamedModule(Path base) throws Exception { 154 Path jar = prepareTestJar(base); 155 156 Path moduleSrc = base.resolve("module-src"); 157 Path m1 = moduleSrc.resolve("m1"); 158 159 Path classes = base.resolve("classes"); 160 161 Files.createDirectories(classes); 162 163 tb.writeJavaFiles(m1, 164 "module m1 { }", 165 "package impl; public class Impl { api.Api api; }"); 166 167 new JavacTask(tb) 168 .options("--class-path", jar.toString(), 169 "--add-reads", "m1=ALL-UNNAMED", 170 "-XDrawDiagnostics") 171 .outdir(classes) 172 .files(findJavaFiles(moduleSrc)) 173 .run() 174 .writeAll(); 175 } 176 177 @Test 178 public void testAddReadsUnnamedModulePackageConflict(Path base) throws Exception { 179 Path jar = prepareTestJar(base); 180 181 Path moduleSrc = base.resolve("module-src"); 182 Path m1 = moduleSrc.resolve("m1"); 183 184 Path classes = base.resolve("classes"); 185 186 Files.createDirectories(classes); 187 188 tb.writeJavaFiles(m1, 189 "module m1 { }", 190 "package api; public class Api { public static void test() { } }", 191 "package impl; public class Impl { { api.Api.test(); } }"); 192 193 new JavacTask(tb) 194 .options("--class-path", jar.toString(), 195 "--module-source-path", moduleSrc.toString(), 196 "--add-reads", "m1=ALL-UNNAMED", 197 "-XDrawDiagnostics") 198 .outdir(classes) 199 .files(m1.resolve("impl").resolve("Impl.java")) 200 .run() 201 .writeAll(); 202 } 203 204 @Test 205 public void testAddReadsUnnamedToJavaBase(Path base) throws Exception { 206 Path jar = prepareTestJar(base); 207 Path src = base.resolve("src"); 208 Path classes = base.resolve("classes"); 209 210 Files.createDirectories(classes); 211 212 tb.writeJavaFiles(src, 213 "package impl; public class Impl { api.Api a; }"); 214 215 new JavacTask(tb) 216 .options("--class-path", jar.toString(), 217 "--add-reads", "java.base=ALL-UNNAMED", 218 "-Xmodule:java.base") 219 .outdir(classes) 220 .files(src.resolve("impl").resolve("Impl.java")) 221 .run() 222 .writeAll(); 223 } 224 225 @Test 226 public void testAddReadsToJavaBase(Path base) throws Exception { 227 Path src = base.resolve("src"); 228 Path classes = base.resolve("classes"); 229 230 Files.createDirectories(classes); 231 232 tb.writeJavaFiles(src, 233 "package impl; public class Impl { javax.swing.JButton b; }"); 234 235 new JavacTask(tb) 236 .options("--add-reads", "java.base=java.desktop", 237 "-Xmodule:java.base") 238 .outdir(classes) 239 .files(findJavaFiles(src)) 240 .run() 241 .writeAll(); 242 } 243 244 private Path prepareTestJar(Path base) throws Exception { 245 Path legacySrc = base.resolve("legacy-src"); 246 tb.writeJavaFiles(legacySrc, 247 "package api; public abstract class Api {}"); 248 Path legacyClasses = base.resolve("legacy-classes"); 249 Files.createDirectories(legacyClasses); 250 251 String log = new JavacTask(tb) 252 .options() 253 .outdir(legacyClasses) 254 .files(findJavaFiles(legacySrc)) 255 .run() 256 .writeAll() 257 .getOutput(Task.OutputKind.DIRECT); 258 259 if (!log.isEmpty()) { 260 throw new Exception("unexpected output: " + log); 261 } 262 263 Path lib = base.resolve("lib"); 264 265 Files.createDirectories(lib); 266 267 Path jar = lib.resolve("test-api-1.0.jar"); 268 269 new JarTask(tb, jar) 270 .baseDir(legacyClasses) 271 .files("api/Api.class") 272 .run(); 273 274 return jar; 275 } 276 277 @Test 278 public void testX(Path base) throws Exception { 279 Path src = base.resolve("src"); 280 Path src_m1 = src.resolve("m1"); 281 tb.writeJavaFiles(src_m1, 282 "module m1 { provides java.lang.Runnable with impl.Impl; }", 283 "package impl; public class Impl implements Runnable { public void run() { } }"); 284 Path classes = base.resolve("classes"); 285 tb.createDirectories(classes); 286 287 new JavacTask(tb) 288 .options("--module-source-path", src.toString()) 289 .outdir(classes) 290 .files(findJavaFiles(src)) 291 .run() 292 .writeAll(); 293 294 Path unnamedSrc = base.resolve("unnamed-src"); 295 Path unnamedClasses = base.resolve("unnamed-classes"); 296 297 Files.createDirectories(unnamedClasses); 298 299 tb.writeJavaFiles(unnamedSrc, 300 "package impl; public class Impl { }"); 301 302 new JavacTask(tb) 303 .options("--add-reads", "m1=ALL-UNNAMED", 304 "-Xmodule:m1", 305 "--module-path", classes.toString()) 306 .outdir(unnamedClasses) 307 .files(findJavaFiles(unnamedSrc)) 308 .run() 309 .writeAll(); 310 } 311} 312