JDK-8133906 : Services should be registered in each Cryptographic Service Provider
  • Type: Enhancement
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 8u60
  • Priority: P3
  • Status: Resolved
  • Resolution: Duplicate
  • OS: solaris_11
  • CPU: sparc
  • Submitted: 2015-08-18
  • Updated: 2020-06-09
  • Resolved: 2016-08-15
Related Reports
Duplicate :  
Relates :  
In the current implementation, only provider PKCS11 register the services in the constructor. For other providers, they do not register the services in advance. 

Thus, when getting a service from a particular provider, inside the getService() method in java.security.Provider.java, it looks up the serviceMap. As the services are not loaded before, the serviceMap is always null and the putService is never called. 

As this getService() is a synchronized method, which causes performance regression when multiple threads are  trying to get service. 
I have changed all providers except those outside of java.base module to use the "Service" model. As for the providers in java.base module, they are already covered by my other bug 7092821. I think we should close this as duplicate of 7092821 which are tracking the same issue.

When I increased the load and I found there are a few threads blocked by this getService(), and when I revisited the code I just found there are two service maps, one of which is duplicate. And also the implementations of provider Ucrypto, SunJCE are inconsistent with PKCS11. But in terms of performance gain, I would not say there is much performance improvement. So it is okay to leave with the current implementation.

In JDK up to 1.4.2, we stored the types of services offered in a Provider map, which is: java.lang.Object java.util.Dictionary<K,V> java.util.Hashtable<Object,Object> java.util.Properties java.security.Provider which would be stored as a Hashtable<String,String>. e.g. "Signature.SHA1withDSA", "sun.security.provider.DSA$SHA1withDSA" In JDK 5, we moved from the String/String representation to a Service mechanism. Providers can be initialized either as before which is much simpler conceptually or using the new Service mechanism. Many of our old providers are stored as before, but PKCS11 is the only one that is initialized using the new style, since Service was invented to support PKCS11. During service lookups, if the provider hasn't been parsed/converted from the Hashtable to be represented by a Service table, it will do in ensureLegacyParsed(). This legacy->Service conversion is done only on the first getService() call for this provider, and only done again if the Hashtable changes. We could parse *ALL* providers at registration time, or continue with the on-demand lazy parsing as we do now, where only those that are needed will be done. I would need to see a definite performance improvement before going with the former.