-
Enhancement
-
Resolution: Fixed
-
P4
-
8u92, 9
-
b04
-
generic
-
generic
A DESCRIPTION OF THE REQUEST :
During an analysis of a java application startup time the following performance problem was found: some libraries create SSLContext. As a part of this context creation sun.security.ssl.TrustManagerFactoryImpl class loads default JDK keystore (jre/lib/security/cacerts). sun.security.ssl.TrustManagerFactoryImpl creates a FileInputStream and passes it to java.security.KeyStore which delegates the load to sun.security.provider.JavaKeyStore#engineStore method. In this method the keystore content is loaded from the provided input stream. TrustManagerFactoryImpl and JavaKeyStore does not create a buffered input stream for this input stream, as a result JavaKeyStore spends time to read a keystore content by few bytes multiple times directly from the file.
Example 1:
java.io.FileInputStream.read() FileInputStream.java
java.io.DataInputStream.readInt() DataInputStream.java:389
sun.security.provider.JavaKeyStore.engineLoad(InputStream, char[]) JavaKeyStore.java:745
sun.security.provider.JavaKeyStore$JKS.engineLoad(InputStream, char[]) JavaKeyStore.java:55
java.security.KeyStore.load(InputStream, char[]) KeyStore.java:1445
sun.security.ssl.TrustManagerFactoryImpl.getCacertsKeyStore(String) TrustManagerFactoryImpl.java:226
sun.security.ssl.SSLContextImpl$DefaultSSLContext.getDefaultTrustManager() SSLContextImpl.java:767
sun.security.ssl.SSLContextImpl$DefaultSSLContext.<init>() SSLContextImpl.java:733
sun.reflect.NativeConstructorAccessorImpl.newInstance(Object[]) NativeConstructorAccessorImpl.java:62
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Object[]) DelegatingConstructorAccessorImpl.java:45
java.lang.reflect.Constructor.newInstance(Object[]) Constructor.java:422
java.security.Provider$Service.newInstance(Object) Provider.java:1595
sun.security.jca.GetInstance.getInstance(Provider$Service, Class) GetInstance.java:236
sun.security.jca.GetInstance.getInstance(String, Class, String) GetInstance.java:164
javax.net.ssl.SSLContext.getInstance(String) SSLContext.java:156
javax.net.ssl.SSLContext.getDefault() SSLContext.java:96
javax.net.ssl.SSLSocketFactory.getDefault() SSLSocketFactory.java:122
org.apache.http.impl.client.HttpClientBuilder.build() HttpClientBuilder.java
io.hawt.web.ProxyServlet.init(ServletConfig) ProxyServlet.java:152
org.eclipse.jetty.servlet.ServletHolder.initServlet() ServletHolder.java:612
Example 2:
java.io.FileInputStream.read() FileInputStream.java
java.io.DataInputStream.readInt() DataInputStream.java:388
sun.security.provider.JavaKeyStore.engineLoad(InputStream, char[]) JavaKeyStore.java:745
sun.security.provider.JavaKeyStore$JKS.engineLoad(InputStream, char[]) JavaKeyStore.java:55
java.security.KeyStore.load(InputStream, char[]) KeyStore.java:1445
sun.security.ssl.TrustManagerFactoryImpl.getCacertsKeyStore(String) TrustManagerFactoryImpl.java:226
sun.security.ssl.TrustManagerFactoryImpl.engineInit(KeyStore) TrustManagerFactoryImpl.java:50
javax.net.ssl.TrustManagerFactory.init(KeyStore) TrustManagerFactory.java:250
shaded.org.apache.http.conn.ssl.SSLContextBuilder.loadTrustMaterial(KeyStore, TrustStrategy) SSLContextBuilder.java:103
JUSTIFICATION :
Many libraries, client applications (like Maven) and application servers initialise SSL on startup, reducing of time to load SSL kestores will reduce startup time for such applications.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
TrustManagerFactoryImpl or JavaKeyStore wrap the FileInputStream into a BufferedInputStream which reduces number of actual file reads
ACTUAL -
JavaKeyStore reads from a raw FileInputStream small portions of data multiple times.
During an analysis of a java application startup time the following performance problem was found: some libraries create SSLContext. As a part of this context creation sun.security.ssl.TrustManagerFactoryImpl class loads default JDK keystore (jre/lib/security/cacerts). sun.security.ssl.TrustManagerFactoryImpl creates a FileInputStream and passes it to java.security.KeyStore which delegates the load to sun.security.provider.JavaKeyStore#engineStore method. In this method the keystore content is loaded from the provided input stream. TrustManagerFactoryImpl and JavaKeyStore does not create a buffered input stream for this input stream, as a result JavaKeyStore spends time to read a keystore content by few bytes multiple times directly from the file.
Example 1:
java.io.FileInputStream.read() FileInputStream.java
java.io.DataInputStream.readInt() DataInputStream.java:389
sun.security.provider.JavaKeyStore.engineLoad(InputStream, char[]) JavaKeyStore.java:745
sun.security.provider.JavaKeyStore$JKS.engineLoad(InputStream, char[]) JavaKeyStore.java:55
java.security.KeyStore.load(InputStream, char[]) KeyStore.java:1445
sun.security.ssl.TrustManagerFactoryImpl.getCacertsKeyStore(String) TrustManagerFactoryImpl.java:226
sun.security.ssl.SSLContextImpl$DefaultSSLContext.getDefaultTrustManager() SSLContextImpl.java:767
sun.security.ssl.SSLContextImpl$DefaultSSLContext.<init>() SSLContextImpl.java:733
sun.reflect.NativeConstructorAccessorImpl.newInstance(Object[]) NativeConstructorAccessorImpl.java:62
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Object[]) DelegatingConstructorAccessorImpl.java:45
java.lang.reflect.Constructor.newInstance(Object[]) Constructor.java:422
java.security.Provider$Service.newInstance(Object) Provider.java:1595
sun.security.jca.GetInstance.getInstance(Provider$Service, Class) GetInstance.java:236
sun.security.jca.GetInstance.getInstance(String, Class, String) GetInstance.java:164
javax.net.ssl.SSLContext.getInstance(String) SSLContext.java:156
javax.net.ssl.SSLContext.getDefault() SSLContext.java:96
javax.net.ssl.SSLSocketFactory.getDefault() SSLSocketFactory.java:122
org.apache.http.impl.client.HttpClientBuilder.build() HttpClientBuilder.java
io.hawt.web.ProxyServlet.init(ServletConfig) ProxyServlet.java:152
org.eclipse.jetty.servlet.ServletHolder.initServlet() ServletHolder.java:612
Example 2:
java.io.FileInputStream.read() FileInputStream.java
java.io.DataInputStream.readInt() DataInputStream.java:388
sun.security.provider.JavaKeyStore.engineLoad(InputStream, char[]) JavaKeyStore.java:745
sun.security.provider.JavaKeyStore$JKS.engineLoad(InputStream, char[]) JavaKeyStore.java:55
java.security.KeyStore.load(InputStream, char[]) KeyStore.java:1445
sun.security.ssl.TrustManagerFactoryImpl.getCacertsKeyStore(String) TrustManagerFactoryImpl.java:226
sun.security.ssl.TrustManagerFactoryImpl.engineInit(KeyStore) TrustManagerFactoryImpl.java:50
javax.net.ssl.TrustManagerFactory.init(KeyStore) TrustManagerFactory.java:250
shaded.org.apache.http.conn.ssl.SSLContextBuilder.loadTrustMaterial(KeyStore, TrustStrategy) SSLContextBuilder.java:103
JUSTIFICATION :
Many libraries, client applications (like Maven) and application servers initialise SSL on startup, reducing of time to load SSL kestores will reduce startup time for such applications.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
TrustManagerFactoryImpl or JavaKeyStore wrap the FileInputStream into a BufferedInputStream which reduces number of actual file reads
ACTUAL -
JavaKeyStore reads from a raw FileInputStream small portions of data multiple times.
- relates to
-
JDK-8193832 Performance of InputStream.readAllBytes() could be improved
-
- Closed
-
-
JDK-8264777 Overload optimized FileInputStream::readAllBytes
-
- Closed
-
- links to
-
Commit(master) openjdk/jdk/2af869b1
-
Review(master) openjdk/jdk/25920