On 4/21/2016 11:10 PM, Wang Weijun wrote: > >> 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). > Got it.
Constructor-Fall-back is not common in general. I think this is only apply to SecureRandom. No problem for known engines. In the new update, there are a few description about SecureRandom, but no control code related to SecureRandom explicitly. A reader like me would have to ask a lot questions before I can understand the logic. For safe, what do you think about adding a check to make sure it is for SecureRandom only (instanceof, etc), or a note so that we don't forgot to revise if thing get changed in the future? A simple update may be: - // For other primitives using params, ctorParamObj should not + // For other known primitives using params, ctorParamObj should not // be null and nsme is thrown, just like before. Thanks, Xuelei