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