GetSystemPackage.java revision 15491:6f390eafc676
1/* 2 * Copyright (c) 2014, 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 * @bug 8060130 27 * @library /lib/testlibrary 28 * @build package2.Class2 GetSystemPackage jdk.testlibrary.* 29 * @summary Test if getSystemPackage() return consistent values for cases 30 * where a manifest is provided or not and ensure only jars on 31 * bootclasspath gets resolved via Package.getSystemPackage 32 * @run main GetSystemPackage 33 */ 34 35import java.io.File; 36import java.io.FileInputStream; 37import java.io.FileNotFoundException; 38import java.io.FileOutputStream; 39import java.io.IOException; 40import java.util.jar.Attributes; 41import java.util.jar.JarEntry; 42import java.util.jar.JarOutputStream; 43import java.util.jar.Manifest; 44import jdk.testlibrary.ProcessTools; 45 46public class GetSystemPackage { 47 48 static final String testClassesDir = System.getProperty("test.classes", "."); 49 static final File tmpFolder = new File(testClassesDir); 50 static final String manifestTitle = "Special JAR"; 51 52 public static void main(String ... args) throws Exception { 53 if (args.length == 0) { 54 buildJarsAndInitiateSystemPackageTest(); 55 return; 56 } 57 switch (args[0]) { 58 case "system-manifest": 59 verifyPackage(true, true); 60 break; 61 case "system-no-manifest": 62 verifyPackage(false, true); 63 break; 64 case "non-system-manifest": 65 verifyPackage(true, false); 66 break; 67 case "non-system-no-manifest": 68 default: 69 verifyPackage(false, false); 70 break; 71 } 72 } 73 74 private static void buildJarsAndInitiateSystemPackageTest() 75 throws Exception 76 { 77 Manifest m = new Manifest(); 78 // not setting MANIFEST_VERSION prevents META-INF/MANIFEST.MF from 79 // getting written 80 m.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); 81 m.getMainAttributes().put(Attributes.Name.SPECIFICATION_TITLE, 82 manifestTitle); 83 84 buildJar("manifest.jar", m); 85 buildJar("no-manifest.jar", null); 86 87 runSubProcess("System package with manifest improperly resolved.", 88 "-Xbootclasspath/a:" + testClassesDir + "/manifest.jar", 89 "GetSystemPackage", "system-manifest"); 90 91 runSubProcess("System package from directory improperly resolved.", 92 "-Xbootclasspath/a:" + testClassesDir, "GetSystemPackage", 93 "system-no-manifest"); 94 95 runSubProcess("System package with no manifest improperly resolved", 96 "-Xbootclasspath/a:" + testClassesDir + "/no-manifest.jar", 97 "GetSystemPackage", "system-no-manifest"); 98 99 runSubProcess("Classpath package with manifest improperly resolved", 100 "-cp", testClassesDir + "/manifest.jar", "GetSystemPackage", 101 "non-system-manifest"); 102 103 runSubProcess("Classpath package with no manifest improperly resolved", 104 "-cp", testClassesDir + "/no-manifest.jar", "GetSystemPackage", 105 "non-system-no-manifest"); 106 107 } 108 109 private static void buildJar(String name, Manifest man) throws Exception { 110 JarBuilder jar = new JarBuilder(tmpFolder, name, man); 111 jar.addClassFile("package2/Class2.class", 112 testClassesDir + "/package2/Class2.class"); 113 jar.addClassFile("GetSystemPackage.class", 114 testClassesDir + "/GetSystemPackage.class"); 115 jar.build(); 116 } 117 118 private static void runSubProcess(String messageOnError, String ... args) 119 throws Exception 120 { 121 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args); 122 int res = pb.directory(tmpFolder).inheritIO().start().waitFor(); 123 if (res != 0) { 124 throw new RuntimeException(messageOnError); 125 } 126 } 127 128 private static void verifyPackage(boolean hasManifest, 129 boolean isSystemPackage) 130 throws Exception 131 { 132 Class<?> c = Class.forName("package2.Class2"); 133 Package pkg = c.getPackage(); 134 if (pkg == null || pkg != Package.getPackage("package2") || 135 !"package2".equals(pkg.getName())) { 136 fail("package2 not found via Package.getPackage()"); 137 } 138 139 String specificationTitle = pkg.getSpecificationTitle(); 140 if (!"package2".equals(pkg.getName())) { 141 fail("Invalid package for Class2"); 142 } 143 144 if (hasManifest && (specificationTitle == null 145 || !manifestTitle.equals(specificationTitle))) { 146 fail("Invalid manifest for package " + pkg.getName()); 147 } 148 if (!hasManifest && specificationTitle != null) { 149 fail("Invalid manifest for package " + pkg.getName() + ": was " + 150 specificationTitle + " expected: null"); 151 } 152 153 ClassLoader ld = c.getClassLoader(); 154 Package systemPkg = ld != null ? null : Package.getPackage("package2"); 155 156 if (findPackage("java.lang") == null) { 157 fail("java.lang not found via Package.getPackages()"); 158 } 159 Package foundPackage = findPackage("package2"); 160 if (isSystemPackage) { 161 if (systemPkg == null) { 162 fail("System package could not be found via getSystemPackage"); 163 } 164 if (foundPackage != systemPkg || systemPkg != pkg) { 165 fail("Inconsistent package found via Package.getPackages()"); 166 } 167 } else { 168 if (systemPkg != null) { 169 fail("Non-system package could be found via getSystemPackage"); 170 } 171 if (foundPackage == null) { 172 fail("Non-system package not found via Package.getPackages()"); 173 } 174 } 175 } 176 177 private static Package findPackage(String name) { 178 Package[] packages = Package.getPackages(); 179 for (Package p : packages) { 180 if (p.getName().equals(name)) { 181 return p; 182 } 183 } 184 return null; 185 } 186 187 private static void fail(String message) { 188 throw new RuntimeException(message); 189 } 190} 191 192/* 193 * Helper class for building jar files 194 */ 195class JarBuilder { 196 197 private JarOutputStream os; 198 199 public JarBuilder(File tmpFolder, String jarName, Manifest manifest) 200 throws FileNotFoundException, IOException 201 { 202 File jarFile = new File(tmpFolder, jarName); 203 if (manifest != null) { 204 this.os = new JarOutputStream(new FileOutputStream(jarFile), 205 manifest); 206 } else { 207 this.os = new JarOutputStream(new FileOutputStream(jarFile)); 208 } 209 } 210 211 public void addClassFile(String pathFromRoot, String file) 212 throws IOException 213 { 214 byte[] buf = new byte[1024]; 215 try (FileInputStream in = new FileInputStream(file)) { 216 JarEntry entry = new JarEntry(pathFromRoot); 217 os.putNextEntry(entry); 218 int len; 219 while ((len = in.read(buf)) > 0) { 220 os.write(buf, 0, len); 221 } 222 os.closeEntry(); 223 } 224 } 225 226 public void build() throws IOException { 227 os.close(); 228 } 229} 230