> On Apr 21, 2016, at 9:44 PM, Xuelei Fan <xuelei....@oracle.com> wrote:
> 
>>> public MyCertStore extends CertStoreSpi {
>>> 
>>>   public MyCertStore() {
>>>       // whatever
>>>       // ;-) Don't ask me why this construct is necessary.
>>>   }
>>> 
>>>   public MyCertStore(XXX params) {
>>>       // throws NoSuchMethodException
>>>       // ;-) Don't ask me why throw this exception.
>>>   }
>>> }
>>> 
>>> newInstanceUtil(MyCertStore, ...)
>>> 
>>> The MyCertStore() would get called, unexpectly.  Am I missing something?
>> 
>> Probably not, unless you call getInstance(arg, null). I am not sure this 
>> null will trigger some other exception along the way.
>> 
>> OK, I admit there is a side effect here: If you design 
>> getInstance(alg,params) but params is always null, then you can only 
>> implement a constructor with no params.
>> 
>> This is stupid and useless, but not really harmful.
>> 
> Can you explain more here?

The code change looks like this

     private static Object newInstanceUtil(final Class<?> clazz,
         final Class<?> ctrParamClz, final Object ctorParamObj)
         throws Exception {
         if (ctrParamClz == null) {
             Constructor<?> con = clazz.getConstructor();
             return con.newInstance();
         } else {
-            Constructor<?> con = clazz.getConstructor(ctrParamClz);
-            return con.newInstance(ctorParamObj);
+            try {
+                Constructor<?> con = clazz.getConstructor(ctrParamClz);
+                return con.newInstance(ctorParamObj);
+            } catch (NoSuchMethodException nsme) {
+                if (ctorParamObj == null) {
+                    try {
+                        Constructor<?> con = clazz.getConstructor();
+                        return con.newInstance();
+                    } catch (NoSuchMethodException nsme2) {
+                        nsme.addSuppressed(nsme2);
+                        throw nsme;
+                    }
+                } else {
+                    throw nsme;
+                }
+            }
         }
     }

So in order for the arg-less constructor to be called, you will need

1. ctrParamClz != null, i.e. there is a getInstance(arg,params) API.

2. ctorParamObj == null, i.e. someone calls it with getInstance(arg) or 
getInstance(arg,null).

3. nsme caught, i.e. the implementation has not provided a constructor with args

This matches the "otherwise" part of what I described in the @implSpec of 
SecureRandomSpi, which I don't suggest new implementation doing it, and is not 
what all non-SecureRandom implementations are doing now (they always have a 
constructor with args).

>>> public MyCertStore(XXX params) {
>>>       // throws NoSuchMethodException
>>>       // ;-) Don't ask me why throw this exception.
>>>   }

When this constructor throws a NoSuchMethodException, calling con.newInstance() 
will throw an InvocationTargetException, the NoSuchMethodException should only 
be caught if clazz.getConstructor(ctrParamClz) fails.


Reply via email to