8035004: Provider provides less service
authormullan
Tue, 01 Apr 2014 11:58:42 -0400
changeset 25542 05badfb785b2
parent 25541 df83fb1a542e
child 25543 6655212b3399
8035004: Provider provides less service Reviewed-by: wetmore, skoivu
jdk/src/share/classes/java/security/Provider.java
--- a/jdk/src/share/classes/java/security/Provider.java	Sat Mar 29 23:24:26 2014 +0000
+++ b/jdk/src/share/classes/java/security/Provider.java	Tue Apr 01 11:58:42 2014 -0400
@@ -1376,7 +1376,7 @@
      * <p>This class defines the methods {@link #supportsParameter
      * supportsParameter()} and {@link #newInstance newInstance()}
      * which are used by the Java security framework when it searches for
-     * suitable services and instantes them. The valid arguments to those
+     * suitable services and instantiates them. The valid arguments to those
      * methods depend on the type of service. For the service types defined
      * within Java SE, see the
      * <a href="../../../technotes/guides/security/crypto/CryptoSpec.html">
@@ -1566,7 +1566,7 @@
          *
          * @throws InvalidParameterException if the value of
          * constructorParameter is invalid for this type of service.
-         * @throws NoSuchAlgorithmException if instantation failed for
+         * @throws NoSuchAlgorithmException if instantiation failed for
          * any other reason.
          */
         public Object newInstance(Object constructorParameter)
@@ -1594,7 +1594,9 @@
                             + " engines");
                     }
                     Class<?> clazz = getImplClass();
-                    return clazz.newInstance();
+                    Class<?>[] empty = {};
+                    Constructor<?> con = clazz.getConstructor(empty);
+                    return con.newInstance();
                 } else {
                     Class<?> paramClass = cap.getConstructorParameterClass();
                     if (constructorParameter != null) {
@@ -1637,13 +1639,18 @@
                     } else {
                         clazz = cl.loadClass(className);
                     }
+                    if (!Modifier.isPublic(clazz.getModifiers())) {
+                        throw new NoSuchAlgorithmException
+                            ("class configured for " + type + " (provider: " +
+                            provider.getName() + ") is not public.");
+                    }
                     classRef = new WeakReference<Class<?>>(clazz);
                 }
                 return clazz;
             } catch (ClassNotFoundException e) {
                 throw new NoSuchAlgorithmException
-                    ("class configured for " + type + "(provider: " +
-                    provider.getName() + ")" + "cannot be found.", e);
+                    ("class configured for " + type + " (provider: " +
+                    provider.getName() + ") cannot be found.", e);
             }
         }
 
@@ -1656,15 +1663,21 @@
                 throws Exception {
             Class<?> clazz = getImplClass();
             if (constructorParameter == null) {
-                Object o = clazz.newInstance();
-                return o;
+                // create instance with public no-arg constructor if it exists
+                try {
+                    Class<?>[] empty = {};
+                    Constructor<?> con = clazz.getConstructor(empty);
+                    return con.newInstance();
+                } catch (NoSuchMethodException e) {
+                    throw new NoSuchAlgorithmException("No public no-arg "
+                        + "constructor found in class " + className);
+                }
             }
             Class<?> argClass = constructorParameter.getClass();
             Constructor<?>[] cons = clazz.getConstructors();
             // find first public constructor that can take the
             // argument as parameter
-            for (int i = 0; i < cons.length; i++) {
-                Constructor<?> con = cons[i];
+            for (Constructor<?> con : cons) {
                 Class<?>[] paramTypes = con.getParameterTypes();
                 if (paramTypes.length != 1) {
                     continue;
@@ -1672,10 +1685,9 @@
                 if (paramTypes[0].isAssignableFrom(argClass) == false) {
                     continue;
                 }
-                Object o = con.newInstance(new Object[] {constructorParameter});
-                return o;
+                return con.newInstance(constructorParameter);
             }
-            throw new NoSuchAlgorithmException("No constructor matching "
+            throw new NoSuchAlgorithmException("No public constructor matching "
                 + argClass.getName() + " found in class " + className);
         }