Fri, 13 Sep 2013 16:45:11 +0530
8024619: JDBC java.sql.DriverManager is not usable from JS script
Reviewed-by: jlaskey, lagergren, attila
1.1 --- a/make/build.xml Thu Sep 12 22:16:40 2013 +0530 1.2 +++ b/make/build.xml Fri Sep 13 16:45:11 2013 +0530 1.3 @@ -230,6 +230,10 @@ 1.4 <compilerarg value="-Xlint:deprecation"/> 1.5 </javac> 1.6 1.7 + <copy todir="${build.test.classes.dir}/META-INF/services"> 1.8 + <fileset dir="${test.src.dir}/META-INF/services/"/> 1.9 + </copy> 1.10 + 1.11 <!-- tests that check nashorn internals and internal API --> 1.12 <jar jarfile="${nashorn.internal.tests.jar}"> 1.13 <fileset dir="${build.test.classes.dir}" excludes="**/api/**"/> 1.14 @@ -238,6 +242,7 @@ 1.15 <!-- tests that check nashorn script engine (jsr-223) API --> 1.16 <jar jarfile="${nashorn.api.tests.jar}"> 1.17 <fileset dir="${build.test.classes.dir}" includes="**/api/**"/> 1.18 + <fileset dir="${build.test.classes.dir}" includes="**/META-INF/**"/> 1.19 </jar> 1.20 1.21 </target>
2.1 --- a/src/jdk/nashorn/internal/runtime/Context.java Thu Sep 12 22:16:40 2013 +0530 2.2 +++ b/src/jdk/nashorn/internal/runtime/Context.java Fri Sep 13 16:45:11 2013 +0530 2.3 @@ -236,6 +236,10 @@ 2.4 private static final ClassLoader myLoader = Context.class.getClassLoader(); 2.5 private static final StructureLoader sharedLoader; 2.6 2.7 + /*package-private*/ ClassLoader getSharedLoader() { 2.8 + return sharedLoader; 2.9 + } 2.10 + 2.11 private static AccessControlContext createNoPermAccCtxt() { 2.12 return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) }); 2.13 } 2.14 @@ -254,7 +258,7 @@ 2.15 sharedLoader = AccessController.doPrivileged(new PrivilegedAction<StructureLoader>() { 2.16 @Override 2.17 public StructureLoader run() { 2.18 - return new StructureLoader(myLoader, null); 2.19 + return new StructureLoader(myLoader); 2.20 } 2.21 }, CREATE_LOADER_ACC_CTXT); 2.22 } 2.23 @@ -599,7 +603,7 @@ 2.24 * @throws ClassNotFoundException if structure class cannot be resolved 2.25 */ 2.26 public static Class<?> forStructureClass(final String fullName) throws ClassNotFoundException { 2.27 - if (System.getSecurityManager() != null && !NashornLoader.isStructureClass(fullName)) { 2.28 + if (System.getSecurityManager() != null && !StructureLoader.isStructureClass(fullName)) { 2.29 throw new ClassNotFoundException(fullName); 2.30 } 2.31 return Class.forName(fullName, true, sharedLoader); 2.32 @@ -792,12 +796,11 @@ 2.33 static Context fromClass(final Class<?> clazz) { 2.34 final ClassLoader loader = clazz.getClassLoader(); 2.35 2.36 - Context context = null; 2.37 - if (loader instanceof NashornLoader) { 2.38 - context = ((NashornLoader)loader).getContext(); 2.39 + if (loader instanceof ScriptLoader) { 2.40 + return ((ScriptLoader)loader).getContext(); 2.41 } 2.42 2.43 - return (context != null) ? context : Context.getContextTrusted(); 2.44 + return Context.getContextTrusted(); 2.45 } 2.46 2.47 private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) { 2.48 @@ -899,7 +902,7 @@ 2.49 new PrivilegedAction<ScriptLoader>() { 2.50 @Override 2.51 public ScriptLoader run() { 2.52 - return new ScriptLoader(sharedLoader, Context.this); 2.53 + return new ScriptLoader(appLoader, Context.this); 2.54 } 2.55 }, CREATE_LOADER_ACC_CTXT); 2.56 }
3.1 --- a/src/jdk/nashorn/internal/runtime/NashornLoader.java Thu Sep 12 22:16:40 2013 +0530 3.2 +++ b/src/jdk/nashorn/internal/runtime/NashornLoader.java Fri Sep 13 16:45:11 2013 +0530 3.3 @@ -38,10 +38,7 @@ 3.4 import jdk.nashorn.tools.Shell; 3.5 3.6 /** 3.7 - * Superclass for Nashorn class loader classes. This stores Context 3.8 - * instance as an instance field. The current context can be 3.9 - * efficiently accessed from a given Class via it's ClassLoader. 3.10 - * 3.11 + * Superclass for Nashorn class loader classes. 3.12 */ 3.13 abstract class NashornLoader extends SecureClassLoader { 3.14 private static final String OBJECTS_PKG = "jdk.nashorn.internal.objects"; 3.15 @@ -69,27 +66,8 @@ 3.16 }; 3.17 } 3.18 3.19 - private final Context context; 3.20 - 3.21 - final Context getContext() { 3.22 - return context; 3.23 - } 3.24 - 3.25 - NashornLoader(final ClassLoader parent, final Context context) { 3.26 + NashornLoader(final ClassLoader parent) { 3.27 super(parent); 3.28 - this.context = context; 3.29 - } 3.30 - 3.31 - 3.32 - /** 3.33 - * Called by subclass after package access check is done 3.34 - * @param name name of the class to be loaded 3.35 - * @param resolve whether the class should be resolved or not 3.36 - * @return Class object 3.37 - * @throws ClassNotFoundException if class cannot be loaded 3.38 - */ 3.39 - protected final Class<?> loadClassTrusted(final String name, final boolean resolve) throws ClassNotFoundException { 3.40 - return super.loadClass(name, resolve); 3.41 } 3.42 3.43 protected static void checkPackageAccess(final String name) { 3.44 @@ -122,10 +100,6 @@ 3.45 return permCollection; 3.46 } 3.47 3.48 - static boolean isStructureClass(final String fullName) { 3.49 - return fullName.startsWith(SCRIPTS_PKG); 3.50 - } 3.51 - 3.52 /** 3.53 * Create a secure URL class loader for the given classpath 3.54 * @param classPath classpath for the loader to search from
4.1 --- a/src/jdk/nashorn/internal/runtime/ScriptLoader.java Thu Sep 12 22:16:40 2013 +0530 4.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptLoader.java Fri Sep 13 16:45:11 2013 +0530 4.3 @@ -33,17 +33,42 @@ 4.4 * 4.5 */ 4.6 final class ScriptLoader extends NashornLoader { 4.7 + private static final String NASHORN_PKG_PREFIX = "jdk.nashorn.internal."; 4.8 + 4.9 + private final Context context; 4.10 + 4.11 + /*package-private*/ Context getContext() { 4.12 + return context; 4.13 + } 4.14 + 4.15 /** 4.16 * Constructor. 4.17 */ 4.18 - ScriptLoader(final StructureLoader parent, final Context context) { 4.19 - super(parent, context); 4.20 + ScriptLoader(final ClassLoader parent, final Context context) { 4.21 + super(parent); 4.22 + this.context = context; 4.23 } 4.24 4.25 @Override 4.26 protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { 4.27 checkPackageAccess(name); 4.28 - return super.loadClassTrusted(name, resolve); 4.29 + try { 4.30 + return super.loadClass(name, resolve); 4.31 + } catch (final ClassNotFoundException | SecurityException e) { 4.32 + // We'll get ClassNotFoundException for Nashorn 'struct' classes. 4.33 + // Also, we'll get SecurityException for jdk.nashorn.internal.* 4.34 + // classes. So, load these using to context's 'shared' loader. 4.35 + // All these classes start with "jdk.nashorn.internal." prefix. 4.36 + try { 4.37 + if (name.startsWith(NASHORN_PKG_PREFIX)) { 4.38 + return context.getSharedLoader().loadClass(name); 4.39 + } 4.40 + } catch (final ClassNotFoundException ignored) { 4.41 + } 4.42 + 4.43 + // throw the original exception from here 4.44 + throw e; 4.45 + } 4.46 } 4.47 4.48 // package-private and private stuff below this point
5.1 --- a/src/jdk/nashorn/internal/runtime/StructureLoader.java Thu Sep 12 22:16:40 2013 +0530 5.2 +++ b/src/jdk/nashorn/internal/runtime/StructureLoader.java Fri Sep 13 16:45:11 2013 +0530 5.3 @@ -34,7 +34,6 @@ 5.4 5.5 /** 5.6 * Responsible for on the fly construction of structure classes. 5.7 - * 5.8 */ 5.9 final class StructureLoader extends NashornLoader { 5.10 private static final String JS_OBJECT_PREFIX_EXTERNAL = binaryName(SCRIPTS_PACKAGE) + '.' + JS_OBJECT_PREFIX.symbolName(); 5.11 @@ -42,27 +41,17 @@ 5.12 /** 5.13 * Constructor. 5.14 */ 5.15 - StructureLoader(final ClassLoader parent, final Context context) { 5.16 - super(parent, context); 5.17 + StructureLoader(final ClassLoader parent) { 5.18 + super(parent); 5.19 } 5.20 5.21 - @Override 5.22 - protected synchronized Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException { 5.23 - // check the cache first 5.24 - final Class<?> loadedClass = findLoadedClass(name); 5.25 - if (loadedClass != null) { 5.26 - if (resolve) { 5.27 - resolveClass(loadedClass); 5.28 - } 5.29 - return loadedClass; 5.30 - } 5.31 - 5.32 - return super.loadClassTrusted(name, resolve); 5.33 + static boolean isStructureClass(final String name) { 5.34 + return name.startsWith(JS_OBJECT_PREFIX_EXTERNAL); 5.35 } 5.36 5.37 @Override 5.38 protected Class<?> findClass(final String name) throws ClassNotFoundException { 5.39 - if (name.startsWith(JS_OBJECT_PREFIX_EXTERNAL)) { 5.40 + if (isStructureClass(name)) { 5.41 return generateClass(name, name.substring(JS_OBJECT_PREFIX_EXTERNAL.length())); 5.42 } 5.43 return super.findClass(name); 5.44 @@ -75,11 +64,7 @@ 5.45 * @return Generated class. 5.46 */ 5.47 private Class<?> generateClass(final String name, final String descriptor) { 5.48 - Context context = getContext(); 5.49 - 5.50 - if (context == null) { 5.51 - context = Context.getContextTrusted(); 5.52 - } 5.53 + final Context context = Context.getContextTrusted(); 5.54 5.55 final byte[] code = new ObjectClassGenerator(context).generate(descriptor); 5.56 return defineClass(name, code, 0, code.length, new ProtectionDomain(null, getPermissions(null)));
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/script/basic/JDK-8024619.js Fri Sep 13 16:45:11 2013 +0530 6.3 @@ -0,0 +1,46 @@ 6.4 +/* 6.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. 6.11 + * 6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.15 + * version 2 for more details (a copy is included in the LICENSE file that 6.16 + * accompanied this code). 6.17 + * 6.18 + * You should have received a copy of the GNU General Public License version 6.19 + * 2 along with this work; if not, write to the Free Software Foundation, 6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.21 + * 6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.23 + * or visit www.oracle.com if you need additional information or have any 6.24 + * questions. 6.25 + */ 6.26 + 6.27 +/** 6.28 + * JDK-8024619: JDBC java.sql.DriverManager is not usable from JS script 6.29 + * 6.30 + * @test 6.31 + * @run 6.32 + */ 6.33 + 6.34 +var DriverManager = Java.type("java.sql.DriverManager"); 6.35 +var e = DriverManager.getDrivers(); 6.36 + 6.37 +var driverFound = false; 6.38 +// check for Nashorn SQL driver 6.39 +while (e.hasMoreElements()) { 6.40 + var driver = e.nextElement(); 6.41 + if (driver.acceptsURL("jdbc:nashorn:")) { 6.42 + driverFound = true; 6.43 + break; 6.44 + } 6.45 +} 6.46 + 6.47 +if (! driverFound) { 6.48 + fail("Nashorn JDBC Driver not found!"); 6.49 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/test/src/META-INF/services/java.sql.Driver Fri Sep 13 16:45:11 2013 +0530 7.3 @@ -0,0 +1,1 @@ 7.4 +jdk.nashorn.api.NashornSQLDriver
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/test/src/jdk/nashorn/api/NashornSQLDriver.java Fri Sep 13 16:45:11 2013 +0530 8.3 @@ -0,0 +1,79 @@ 8.4 +/* 8.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.7 + * 8.8 + * This code is free software; you can redistribute it and/or modify it 8.9 + * under the terms of the GNU General Public License version 2 only, as 8.10 + * published by the Free Software Foundation. Oracle designates this 8.11 + * particular file as subject to the "Classpath" exception as provided 8.12 + * by Oracle in the LICENSE file that accompanied this code. 8.13 + * 8.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 8.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 8.17 + * version 2 for more details (a copy is included in the LICENSE file that 8.18 + * accompanied this code). 8.19 + * 8.20 + * You should have received a copy of the GNU General Public License version 8.21 + * 2 along with this work; if not, write to the Free Software Foundation, 8.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 8.23 + * 8.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 8.25 + * or visit www.oracle.com if you need additional information or have any 8.26 + * questions. 8.27 + */ 8.28 + 8.29 +package jdk.nashorn.api; 8.30 + 8.31 +import java.sql.*; 8.32 +import java.util.Properties; 8.33 +import java.util.logging.Logger; 8.34 + 8.35 +/** 8.36 + * A dummy SQL driver for testing purpose. 8.37 + */ 8.38 +public final class NashornSQLDriver implements Driver { 8.39 + static { 8.40 + try { 8.41 + DriverManager.registerDriver(new NashornSQLDriver(), null); 8.42 + } catch (SQLException se) { 8.43 + throw new RuntimeException(se); 8.44 + } 8.45 + } 8.46 + 8.47 + @Override 8.48 + public boolean acceptsURL(String url) { 8.49 + return url.startsWith("jdbc:nashorn:"); 8.50 + } 8.51 + 8.52 + @Override 8.53 + public Connection connect(String url, Properties info) { 8.54 + throw new UnsupportedOperationException("I am a dummy!!"); 8.55 + } 8.56 + 8.57 + @Override 8.58 + public int getMajorVersion() { 8.59 + return -1; 8.60 + } 8.61 + 8.62 + @Override 8.63 + public int getMinorVersion() { 8.64 + return -1; 8.65 + } 8.66 + 8.67 + @Override 8.68 + public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) { 8.69 + return new DriverPropertyInfo[0]; 8.70 + } 8.71 + 8.72 + @Override 8.73 + public boolean jdbcCompliant() { 8.74 + // no way! 8.75 + return false; 8.76 + } 8.77 + 8.78 + @Override 8.79 + public Logger getParentLogger() throws SQLFeatureNotSupportedException { 8.80 + throw new SQLFeatureNotSupportedException(); 8.81 + } 8.82 +}