NashornLoader.java revision 1502:752ca580b176
1143247Sphantom/* 2143247Sphantom * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3143247Sphantom * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4143247Sphantom * 5143247Sphantom * This code is free software; you can redistribute it and/or modify it 6143247Sphantom * under the terms of the GNU General Public License version 2 only, as 7143247Sphantom * published by the Free Software Foundation. Oracle designates this 8143247Sphantom * particular file as subject to the "Classpath" exception as provided 9143247Sphantom * by Oracle in the LICENSE file that accompanied this code. 10143247Sphantom * 11143247Sphantom * This code is distributed in the hope that it will be useful, but WITHOUT 12143247Sphantom * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13143247Sphantom * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14143247Sphantom * version 2 for more details (a copy is included in the LICENSE file that 15143247Sphantom * accompanied this code). 16143247Sphantom * 17143247Sphantom * You should have received a copy of the GNU General Public License version 18143247Sphantom * 2 along with this work; if not, write to the Free Software Foundation, 19143247Sphantom * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20143247Sphantom * 21143247Sphantom * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22143247Sphantom * or visit www.oracle.com if you need additional information or have any 23143247Sphantom * questions. 24143247Sphantom */ 25143247Sphantom 26143247Sphantompackage jdk.nashorn.internal.runtime; 27143247Sphantom 28143247Sphantomimport java.io.File; 29143247Sphantomimport java.io.IOException; 30143247Sphantomimport java.net.MalformedURLException; 31143247Sphantomimport java.net.URL; 32143247Sphantomimport java.net.URLClassLoader; 33143247Sphantomimport java.security.CodeSource; 34143247Sphantomimport java.security.Permission; 35143247Sphantomimport java.security.PermissionCollection; 36143247Sphantomimport java.security.Permissions; 37143247Sphantomimport java.security.SecureClassLoader; 38143247Sphantom 39143247Sphantom/** 40143247Sphantom * Superclass for Nashorn class loader classes. 41143247Sphantom */ 42143247Sphantomabstract class NashornLoader extends SecureClassLoader { 43143247Sphantom private static final String OBJECTS_PKG = "jdk.nashorn.internal.objects"; 44143247Sphantom private static final String RUNTIME_PKG = "jdk.nashorn.internal.runtime"; 45143247Sphantom private static final String RUNTIME_ARRAYS_PKG = "jdk.nashorn.internal.runtime.arrays"; 46143247Sphantom private static final String RUNTIME_LINKER_PKG = "jdk.nashorn.internal.runtime.linker"; 47143247Sphantom private static final String SCRIPTS_PKG = "jdk.nashorn.internal.scripts"; 48143247Sphantom 49143247Sphantom private static final Permission[] SCRIPT_PERMISSIONS; 50143247Sphantom 51143247Sphantom static { 52143247Sphantom /* 53143247Sphantom * Generated classes get access to runtime, runtime.linker, objects, scripts packages. 54143247Sphantom * Note that the actual scripts can not access these because Java.type, Packages 55143247Sphantom * prevent these restricted packages. And Java reflection and JSR292 access is prevented 56143247Sphantom * for scripts. In other words, nashorn generated portions of script classes can access 57143247Sphantom * classes in these implementation packages. 58143247Sphantom */ 59143247Sphantom SCRIPT_PERMISSIONS = new Permission[] { 60143247Sphantom new RuntimePermission("accessClassInPackage." + RUNTIME_PKG), 61143247Sphantom new RuntimePermission("accessClassInPackage." + RUNTIME_LINKER_PKG), 62143247Sphantom new RuntimePermission("accessClassInPackage." + OBJECTS_PKG), 63143247Sphantom new RuntimePermission("accessClassInPackage." + SCRIPTS_PKG), 64143247Sphantom new RuntimePermission("accessClassInPackage." + RUNTIME_ARRAYS_PKG) 65143247Sphantom }; 66143247Sphantom } 67143247Sphantom 68143247Sphantom NashornLoader(final ClassLoader parent) { 69143247Sphantom super(parent); 70143247Sphantom } 71143247Sphantom 72143247Sphantom protected static void checkPackageAccess(final String name) { 73143247Sphantom final int i = name.lastIndexOf('.'); 74143247Sphantom if (i != -1) { 75143247Sphantom final SecurityManager sm = System.getSecurityManager(); 76143247Sphantom if (sm != null) { 77143247Sphantom final String pkgName = name.substring(0, i); 78143247Sphantom switch (pkgName) { 79143247Sphantom case RUNTIME_PKG: 80143247Sphantom case RUNTIME_ARRAYS_PKG: 81143247Sphantom case RUNTIME_LINKER_PKG: 82143247Sphantom case OBJECTS_PKG: 83143247Sphantom case SCRIPTS_PKG: 84143247Sphantom // allow it. 85143247Sphantom break; 86143247Sphantom default: 87143247Sphantom sm.checkPackageAccess(pkgName); 88143247Sphantom } 89143247Sphantom } 90143247Sphantom } 91143247Sphantom } 92143247Sphantom 93143247Sphantom @Override 94143247Sphantom protected PermissionCollection getPermissions(final CodeSource codesource) { 95143247Sphantom final Permissions permCollection = new Permissions(); 96143247Sphantom for (final Permission perm : SCRIPT_PERMISSIONS) { 97143247Sphantom permCollection.add(perm); 98143247Sphantom } 99143247Sphantom return permCollection; 100143247Sphantom } 101143247Sphantom 102143247Sphantom /** 103143247Sphantom * Create a secure URL class loader for the given classpath 104143247Sphantom * @param classPath classpath for the loader to search from 105143247Sphantom * @param parent the parent class loader for the new class loader 106143247Sphantom * @return the class loader 107143247Sphantom */ 108143247Sphantom static ClassLoader createClassLoader(final String classPath, final ClassLoader parent) { 109143247Sphantom final URL[] urls = pathToURLs(classPath); 110143247Sphantom return URLClassLoader.newInstance(urls, parent); 111143247Sphantom } 112143247Sphantom 113143247Sphantom /* 114143247Sphantom * Utility method for converting a search path string to an array 115143247Sphantom * of directory and JAR file URLs. 116143247Sphantom * 117143247Sphantom * @param path the search path string 118143247Sphantom * @return the resulting array of directory and JAR file URLs 119143247Sphantom */ 120143247Sphantom private static URL[] pathToURLs(final String path) { 121143247Sphantom final String[] components = path.split(File.pathSeparator); 122143247Sphantom URL[] urls = new URL[components.length]; 123143247Sphantom int count = 0; 124143247Sphantom while(count < components.length) { 125143247Sphantom final URL url = fileToURL(new File(components[count])); 126143247Sphantom if (url != null) { 127143247Sphantom urls[count++] = url; 128143247Sphantom } 129143247Sphantom } 130143247Sphantom if (urls.length != count) { 131143247Sphantom final URL[] tmp = new URL[count]; 132143247Sphantom System.arraycopy(urls, 0, tmp, 0, count); 133143247Sphantom urls = tmp; 134143247Sphantom } 135143247Sphantom return urls; 136143247Sphantom } 137143247Sphantom 138143247Sphantom /* 139143247Sphantom * Returns the directory or JAR file URL corresponding to the specified 140143247Sphantom * local file name. 141143247Sphantom * 142143247Sphantom * @param file the File object 143143247Sphantom * @return the resulting directory or JAR file URL, or null if unknown 144143247Sphantom */ 145143247Sphantom private static URL fileToURL(final File file) { 146143247Sphantom String name; 147143247Sphantom try { 148143247Sphantom name = file.getCanonicalPath(); 149143247Sphantom } catch (final IOException e) { 150143247Sphantom name = file.getAbsolutePath(); 151143247Sphantom } 152143247Sphantom name = name.replace(File.separatorChar, '/'); 153143247Sphantom if (!name.startsWith("/")) { 154143247Sphantom name = "/" + name; 155143247Sphantom } 156143247Sphantom // If the file does not exist, then assume that it's a directory 157143247Sphantom if (!file.isFile()) { 158143247Sphantom name += "/"; 159143247Sphantom } 160143247Sphantom try { 161143247Sphantom return new URL("file", "", name); 162143247Sphantom } catch (final MalformedURLException e) { 163143247Sphantom throw new IllegalArgumentException("file"); 164143247Sphantom } 165143247Sphantom } 166143247Sphantom} 167143247Sphantom 168143247Sphantom