1 /* 2 * Copyright (c) 2015, 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 Basic test of package-info in named module and duplicate 27 * package-info in unnamed module 28 * @modules java.compiler 29 * java.desktop 30 * jdk.compiler 31 * jdk.xml.dom 32 * @build jdk.xml.dom/org.w3c.dom.css.Fake 33 * jdk.xml.dom/org.w3c.dom.css.FakePackage 34 * @compile/module=jdk.xml.dom org/w3c/dom/css/package-info.java 35 * @compile package-info.java PackageInfoTest.java 36 * @run testng p.PackageInfoTest 37 */ 38 39 package p; 40 41 import java.io.IOException; 42 import java.io.UncheckedIOException; 43 import java.lang.annotation.Annotation; 44 import java.net.URL; 45 import java.net.URLClassLoader; 46 import java.nio.file.Files; 47 import java.nio.file.Path; 48 import java.nio.file.Paths; 49 import java.util.ArrayList; 50 import java.util.Arrays; 51 import java.util.List; 52 53 import org.testng.annotations.DataProvider; 54 import org.testng.annotations.Test; 55 import org.w3c.dom.css.CSSRule; 56 57 import javax.tools.JavaCompiler; 58 import javax.tools.JavaFileObject; 59 import javax.tools.StandardJavaFileManager; 60 import javax.tools.ToolProvider; 61 62 import static org.testng.Assert.*; 63 64 public class PackageInfoTest { 65 @DataProvider(name = "jdkClasses") 66 public Object[][] jdkClasses() { 67 return new Object[][] { 68 { java.awt.Button.class, null }, 69 { java.lang.Object.class, null }, 70 { org.w3c.dom.css.CSSRule.class, null }, 71 { loadClass("org.w3c.dom.css.Fake"), loadClass("org.w3c.dom.css.FakePackage") }, 72 }; 73 } 74 75 @Test(dataProvider = "jdkClasses") 76 public void testPackageInfo(Class<?> type, Class<? extends Annotation> annType) { 77 Package pkg = type.getPackage(); 78 assertTrue(pkg.isSealed()); 79 assertTrue(annType == null || pkg.getDeclaredAnnotations().length != 0); 80 if (annType != null) { 81 assertTrue(pkg.isAnnotationPresent(annType)); 82 } 83 } 84 85 private Class<?> loadClass(String name) { 86 return Class.forName(CSSRule.class.getModule(), name); 87 } 88 89 @DataProvider(name = "classpathClasses") 90 public Object[][] cpClasses() throws IOException, ClassNotFoundException { 91 // these classes will be loaded from classpath in unnamed module 92 return new Object[][]{ 93 { p.PackageInfoTest.class, Deprecated.class } 94 }; 95 } 96 97 @Test(dataProvider = "classpathClasses") 98 public void testClassPathPackage(Class<?> type, Class<? extends Annotation> annType) { 99 Package pkg = type.getPackage(); 100 assertTrue(pkg.isSealed() == false); 101 assertTrue(pkg.isAnnotationPresent(annType)); 102 } 103 104 static final String[] otherClasses = new String[] { 105 "p/package-info.class", 106 "p/Duplicate.class", 107 "p/Bar.class" 108 }; 109 110 @Test 111 public void testDuplicatePackage() throws Exception { 112 // a custom class loader loading another package p annotated with @Duplicate 113 Path classes = Paths.get(System.getProperty("test.classes", "."), "tmp"); 114 Files.createDirectories(classes); 115 URLClassLoader loader = new URLClassLoader(new URL[] { classes.toUri().toURL() }); 116 117 // clean up before compiling classes 118 Arrays.stream(otherClasses) 119 .forEach(c -> { 120 try { 121 Files.deleteIfExists(classes.resolve(c)); 122 } catch (IOException e) { 123 throw new UncheckedIOException(e); 124 } 125 }); 126 127 Path src = Paths.get(System.getProperty("test.src", "."), "src", "p"); 128 compile(classes, 129 src.resolve("package-info.java"), 130 src.resolve("Duplicate.java"), 131 src.resolve("Bar.java")); 132 133 // verify if classes are present 134 Arrays.stream(otherClasses) 135 .forEach(c -> { 136 if (Files.notExists(classes.resolve(c))) { 137 throw new RuntimeException(c + " not exist"); 138 } 139 }); 140 141 Class<?> c = Class.forName("p.Bar", true, loader); 142 assertTrue(c.getClassLoader() == loader); 143 assertTrue(this.getClass().getClassLoader() != loader); 144 145 // package p defined by the custom class loader 146 Package pkg = c.getPackage(); 147 assertTrue(pkg.getName().equals("p")); 148 assertTrue(pkg.isSealed() == false); 149 150 // package p defined by the application class loader 151 Package p = this.getClass().getPackage(); 152 assertTrue(p.getName().equals("p")); 153 assertTrue(p != pkg); 154 155 Arrays.stream(pkg.getDeclaredAnnotations()) 156 .forEach(ann -> System.out.format("%s @%s%n", pkg.getName(), ann)); 157 158 Arrays.stream(p.getDeclaredAnnotations()) 159 .forEach(ann -> System.out.format("%s @%s%n", p.getName(), ann)); 160 161 // local package p defined by loader 162 Class<? extends Annotation> ann = 163 (Class<? extends Annotation>)Class.forName("p.Duplicate", false, loader); 164 assertTrue(pkg.isAnnotationPresent(ann)); 165 } 166 167 private void compile(Path destDir, Path... files) throws IOException { 168 compile(null, destDir, files); 169 } 170 171 private void compile(String option, Path destDir, Path... files) 172 throws IOException 173 { 174 System.err.println("compile..."); 175 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 176 try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { 177 Iterable<? extends JavaFileObject> fileObjects = 178 fm.getJavaFileObjectsFromPaths(Arrays.asList(files)); 179 180 List<String> options = new ArrayList<>(); 181 if (option != null) { 182 options.add(option); 183 } 184 if (destDir != null) { 185 options.add("-d"); 186 options.add(destDir.toString()); 187 } 188 options.add("-cp"); 189 options.add(System.getProperty("test.classes", ".")); 190 191 JavaCompiler.CompilationTask task = 192 compiler.getTask(null, fm, null, options, null, fileObjects); 193 if (!task.call()) 194 throw new AssertionError("compilation failed"); 195 } 196 } 197 198 }