NashornLoader.java revision 1350:3cb11f4d617e
1/* 2 * Copyright (c) 2010, 2013, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package jdk.nashorn.internal.runtime; 27 28import java.io.File; 29import java.io.IOException; 30import java.net.MalformedURLException; 31import java.net.URL; 32import java.net.URLClassLoader; 33import java.security.CodeSource; 34import java.security.Permission; 35import java.security.PermissionCollection; 36import java.security.Permissions; 37import java.security.SecureClassLoader; 38import jdk.nashorn.tools.Shell; 39 40/** 41 * Superclass for Nashorn class loader classes. 42 */ 43abstract class NashornLoader extends SecureClassLoader { 44 private static final String OBJECTS_PKG = "jdk.nashorn.internal.objects"; 45 private static final String RUNTIME_PKG = "jdk.nashorn.internal.runtime"; 46 private static final String RUNTIME_ARRAYS_PKG = "jdk.nashorn.internal.runtime.arrays"; 47 private static final String RUNTIME_LINKER_PKG = "jdk.nashorn.internal.runtime.linker"; 48 private static final String SCRIPTS_PKG = "jdk.nashorn.internal.scripts"; 49 50 private static final Permission[] SCRIPT_PERMISSIONS; 51 52 static { 53 /* 54 * Generated classes get access to runtime, runtime.linker, objects, scripts packages. 55 * Note that the actual scripts can not access these because Java.type, Packages 56 * prevent these restricted packages. And Java reflection and JSR292 access is prevented 57 * for scripts. In other words, nashorn generated portions of script classes can access 58 * classes in these implementation packages. 59 */ 60 SCRIPT_PERMISSIONS = new Permission[] { 61 new RuntimePermission("accessClassInPackage." + RUNTIME_PKG), 62 new RuntimePermission("accessClassInPackage." + RUNTIME_LINKER_PKG), 63 new RuntimePermission("accessClassInPackage." + OBJECTS_PKG), 64 new RuntimePermission("accessClassInPackage." + SCRIPTS_PKG), 65 new RuntimePermission("accessClassInPackage." + RUNTIME_ARRAYS_PKG) 66 }; 67 } 68 69 NashornLoader(final ClassLoader parent) { 70 super(parent); 71 } 72 73 protected static void checkPackageAccess(final String name) { 74 final int i = name.lastIndexOf('.'); 75 if (i != -1) { 76 final SecurityManager sm = System.getSecurityManager(); 77 if (sm != null) { 78 final String pkgName = name.substring(0, i); 79 switch (pkgName) { 80 case RUNTIME_PKG: 81 case RUNTIME_ARRAYS_PKG: 82 case RUNTIME_LINKER_PKG: 83 case OBJECTS_PKG: 84 case SCRIPTS_PKG: 85 // allow it. 86 break; 87 default: 88 sm.checkPackageAccess(pkgName); 89 } 90 } 91 } 92 } 93 94 @Override 95 protected PermissionCollection getPermissions(final CodeSource codesource) { 96 final Permissions permCollection = new Permissions(); 97 for (final Permission perm : SCRIPT_PERMISSIONS) { 98 permCollection.add(perm); 99 } 100 return permCollection; 101 } 102 103 /** 104 * Create a secure URL class loader for the given classpath 105 * @param classPath classpath for the loader to search from 106 * @return the class loader 107 */ 108 static ClassLoader createClassLoader(final String classPath) { 109 final ClassLoader parent = Shell.class.getClassLoader(); 110 final URL[] urls = pathToURLs(classPath); 111 return URLClassLoader.newInstance(urls, parent); 112 } 113 114 /* 115 * Utility method for converting a search path string to an array 116 * of directory and JAR file URLs. 117 * 118 * @param path the search path string 119 * @return the resulting array of directory and JAR file URLs 120 */ 121 private static URL[] pathToURLs(final String path) { 122 final String[] components = path.split(File.pathSeparator); 123 URL[] urls = new URL[components.length]; 124 int count = 0; 125 while(count < components.length) { 126 final URL url = fileToURL(new File(components[count])); 127 if (url != null) { 128 urls[count++] = url; 129 } 130 } 131 if (urls.length != count) { 132 final URL[] tmp = new URL[count]; 133 System.arraycopy(urls, 0, tmp, 0, count); 134 urls = tmp; 135 } 136 return urls; 137 } 138 139 /* 140 * Returns the directory or JAR file URL corresponding to the specified 141 * local file name. 142 * 143 * @param file the File object 144 * @return the resulting directory or JAR file URL, or null if unknown 145 */ 146 private static URL fileToURL(final File file) { 147 String name; 148 try { 149 name = file.getCanonicalPath(); 150 } catch (final IOException e) { 151 name = file.getAbsolutePath(); 152 } 153 name = name.replace(File.separatorChar, '/'); 154 if (!name.startsWith("/")) { 155 name = "/" + name; 156 } 157 // If the file does not exist, then assume that it's a directory 158 if (!file.isFile()) { 159 name += "/"; 160 } 161 try { 162 return new URL("file", "", name); 163 } catch (final MalformedURLException e) { 164 throw new IllegalArgumentException("file"); 165 } 166 } 167} 168 169