8024619: JDBC java.sql.DriverManager is not usable from JS script

Fri, 13 Sep 2013 16:45:11 +0530

author
sundar
date
Fri, 13 Sep 2013 16:45:11 +0530
changeset 552
8b0914b25430
parent 551
917b16e509bd
child 553
5683eca2967a

8024619: JDBC java.sql.DriverManager is not usable from JS script
Reviewed-by: jlaskey, lagergren, attila

make/build.xml file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/Context.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/NashornLoader.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/ScriptLoader.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/StructureLoader.java file | annotate | diff | comparison | revisions
test/script/basic/JDK-8024619.js file | annotate | diff | comparison | revisions
test/src/META-INF/services/java.sql.Driver file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/api/NashornSQLDriver.java file | annotate | diff | comparison | revisions
     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 +}

mercurial