NashornLoader.java revision 953:221a84ef44c0
11590Srgrimes/* 21590Srgrimes * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 31590Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41590Srgrimes * 51590Srgrimes * This code is free software; you can redistribute it and/or modify it 61590Srgrimes * under the terms of the GNU General Public License version 2 only, as 71590Srgrimes * published by the Free Software Foundation. Oracle designates this 81590Srgrimes * particular file as subject to the "Classpath" exception as provided 91590Srgrimes * by Oracle in the LICENSE file that accompanied this code. 101590Srgrimes * 111590Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT 121590Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 131590Srgrimes * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 141590Srgrimes * version 2 for more details (a copy is included in the LICENSE file that 151590Srgrimes * accompanied this code). 161590Srgrimes * 171590Srgrimes * You should have received a copy of the GNU General Public License version 181590Srgrimes * 2 along with this work; if not, write to the Free Software Foundation, 191590Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 201590Srgrimes * 211590Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 221590Srgrimes * or visit www.oracle.com if you need additional information or have any 231590Srgrimes * questions. 241590Srgrimes */ 251590Srgrimes 261590Srgrimespackage jdk.nashorn.internal.runtime; 271590Srgrimes 281590Srgrimesimport java.io.File; 291590Srgrimesimport java.io.IOException; 3087628Sdwmaloneimport java.net.MalformedURLException; 3187628Sdwmaloneimport java.net.URL; 3287628Sdwmaloneimport java.net.URLClassLoader; 3387628Sdwmaloneimport java.security.CodeSource; 3487628Sdwmaloneimport java.security.Permission; 3587628Sdwmaloneimport java.security.PermissionCollection; 3687249Smarkmimport java.security.Permissions; 3787249Smarkmimport java.security.SecureClassLoader; 3887249Smarkmimport jdk.nashorn.tools.Shell; 391590Srgrimes 401590Srgrimes/** 411590Srgrimes * Superclass for Nashorn class loader classes. 421590Srgrimes */ 431590Srgrimesabstract class NashornLoader extends SecureClassLoader { 441590Srgrimes private static final String OBJECTS_PKG = "jdk.nashorn.internal.objects"; 451590Srgrimes private static final String RUNTIME_PKG = "jdk.nashorn.internal.runtime"; 461590Srgrimes private static final String RUNTIME_ARRAYS_PKG = "jdk.nashorn.internal.runtime.arrays"; 4792920Simp private static final String RUNTIME_LINKER_PKG = "jdk.nashorn.internal.runtime.linker"; 4892920Simp private static final String SCRIPTS_PKG = "jdk.nashorn.internal.scripts"; 491590Srgrimes 501590Srgrimes private static final Permission[] SCRIPT_PERMISSIONS; 511590Srgrimes 521590Srgrimes static { 531590Srgrimes /* 541590Srgrimes * Generated classes get access to runtime, runtime.linker, objects, scripts packages. 55100822Sdwmalone * Note that the actual scripts can not access these because Java.type, Packages 561590Srgrimes * prevent these restricted packages. And Java reflection and JSR292 access is prevented 571590Srgrimes * for scripts. In other words, nashorn generated portions of script classes can access 581590Srgrimes * classes in these implementation packages. 591590Srgrimes */ 601590Srgrimes SCRIPT_PERMISSIONS = new Permission[] { 611590Srgrimes new RuntimePermission("accessClassInPackage." + RUNTIME_PKG), 621590Srgrimes new RuntimePermission("accessClassInPackage." + RUNTIME_LINKER_PKG), 631590Srgrimes new RuntimePermission("accessClassInPackage." + OBJECTS_PKG), 641590Srgrimes new RuntimePermission("accessClassInPackage." + SCRIPTS_PKG), 651590Srgrimes new RuntimePermission("accessClassInPackage." + RUNTIME_ARRAYS_PKG) 661590Srgrimes }; 671590Srgrimes } 6887750Scharnier 691590Srgrimes NashornLoader(final ClassLoader parent) { 701590Srgrimes super(parent); 711590Srgrimes } 721590Srgrimes 731590Srgrimes protected static void checkPackageAccess(final String name) { 741590Srgrimes final int i = name.lastIndexOf('.'); 7597574Stjr if (i != -1) { 761590Srgrimes final SecurityManager sm = System.getSecurityManager(); 771590Srgrimes if (sm != null) { 781590Srgrimes final String pkgName = name.substring(0, i); 791590Srgrimes switch (pkgName) { 801590Srgrimes case RUNTIME_PKG: 811590Srgrimes case RUNTIME_ARRAYS_PKG: 821590Srgrimes case RUNTIME_LINKER_PKG: 831590Srgrimes case OBJECTS_PKG: 841590Srgrimes case SCRIPTS_PKG: 851590Srgrimes // allow it. 861590Srgrimes break; 871590Srgrimes default: 881590Srgrimes sm.checkPackageAccess(pkgName); 891590Srgrimes } 901590Srgrimes } 911590Srgrimes } 921590Srgrimes } 931590Srgrimes 941590Srgrimes @Override 95100822Sdwmalone protected PermissionCollection getPermissions(final CodeSource codesource) { 961590Srgrimes final Permissions permCollection = new Permissions(); 971590Srgrimes for (final Permission perm : SCRIPT_PERMISSIONS) { 981590Srgrimes permCollection.add(perm); 9997581Stjr } 1001590Srgrimes return permCollection; 1011590Srgrimes } 1021590Srgrimes 1031590Srgrimes /** 1041590Srgrimes * Create a secure URL class loader for the given classpath 1051590Srgrimes * @param classPath classpath for the loader to search from 1061590Srgrimes * @return the class loader 1071590Srgrimes */ 1081590Srgrimes static ClassLoader createClassLoader(final String classPath) { 1091590Srgrimes final ClassLoader parent = Shell.class.getClassLoader(); 1101590Srgrimes final URL[] urls = pathToURLs(classPath); 1111590Srgrimes return URLClassLoader.newInstance(urls, parent); 1121590Srgrimes } 1131590Srgrimes 1141590Srgrimes /* 1151590Srgrimes * Utility method for converting a search path string to an array 1161590Srgrimes * of directory and JAR file URLs. 1171590Srgrimes * 1181590Srgrimes * @param path the search path string 1191590Srgrimes * @return the resulting array of directory and JAR file URLs 1201590Srgrimes */ 1211590Srgrimes private static URL[] pathToURLs(final String path) { 1221590Srgrimes final String[] components = path.split(File.pathSeparator); 123100822Sdwmalone URL[] urls = new URL[components.length]; 1241590Srgrimes int count = 0; 125166501Srse while(count < components.length) { 1261590Srgrimes final URL url = fileToURL(new File(components[count])); 1271590Srgrimes if (url != null) { 1281590Srgrimes urls[count++] = url; 129166501Srse } 1301590Srgrimes } 131166501Srse if (urls.length != count) { 1321590Srgrimes final URL[] tmp = new URL[count]; 1331590Srgrimes 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 = 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