Providers: Eagerly initialize default providers.
Also change ProviderConfig to try loading providers on the boot
classpath before attempting the System class loader. This lets us
initialize things at compile time.
bug: 27805718
Change-Id: I4f33c752c0cb1e96f5b8c863fc32413cc8ec7fa0
diff --git a/ojluni/src/main/java/sun/security/jca/ProviderConfig.java b/ojluni/src/main/java/sun/security/jca/ProviderConfig.java
index 62f8bdd..fc4ee76 100755
--- a/ojluni/src/main/java/sun/security/jca/ProviderConfig.java
+++ b/ojluni/src/main/java/sun/security/jca/ProviderConfig.java
@@ -208,58 +208,68 @@
if (debug != null) {
debug.println("Loading provider: " + ProviderConfig.this);
}
+
try {
- ClassLoader cl = ClassLoader.getSystemClassLoader();
- Class<?> provClass;
- if (cl != null) {
- provClass = cl.loadClass(className);
- } else {
- provClass = Class.forName(className);
- }
- Object obj;
- if (hasArgument() == false) {
- obj = provClass.newInstance();
- } else {
- Constructor<?> cons = provClass.getConstructor(CL_STRING);
- obj = cons.newInstance(argument);
- }
- if (obj instanceof Provider) {
- if (debug != null) {
- debug.println("Loaded provider " + obj);
+ // First try with the boot classloader.
+ return initProvider(className, Object.class.getClassLoader());
+ } catch (Exception e1) {
+ // If that fails, try with the system classloader.
+ try {
+ return initProvider(className, ClassLoader.getSystemClassLoader());
+ } catch (Exception e) {
+ Throwable t;
+ if (e instanceof InvocationTargetException) {
+ t = ((InvocationTargetException)e).getCause();
+ } else {
+ t = e;
}
- return (Provider)obj;
- } else {
if (debug != null) {
- debug.println(className + " is not a provider");
+ debug.println("Error loading provider " + ProviderConfig.this);
+ t.printStackTrace();
}
- disableLoad();
+ // provider indicates fatal error, pass through exception
+ if (t instanceof ProviderException) {
+ throw (ProviderException)t;
+ }
+ // provider indicates that loading should not be retried
+ if (t instanceof UnsupportedOperationException) {
+ disableLoad();
+ }
return null;
}
- } catch (Exception e) {
- Throwable t;
- if (e instanceof InvocationTargetException) {
- t = ((InvocationTargetException)e).getCause();
- } else {
- t = e;
- }
- if (debug != null) {
- debug.println("Error loading provider " + ProviderConfig.this);
- t.printStackTrace();
- }
- // provider indicates fatal error, pass through exception
- if (t instanceof ProviderException) {
- throw (ProviderException)t;
- }
- // provider indicates that loading should not be retried
- if (t instanceof UnsupportedOperationException) {
- disableLoad();
- }
- return null;
}
}
});
}
+ private Provider initProvider(String className, ClassLoader cl) throws Exception {
+ Class<?> provClass;
+ if (cl != null) {
+ provClass = cl.loadClass(className);
+ } else {
+ provClass = Class.forName(className);
+ }
+ Object obj;
+ if (hasArgument() == false) {
+ obj = provClass.newInstance();
+ } else {
+ Constructor<?> cons = provClass.getConstructor(CL_STRING);
+ obj = cons.newInstance(argument);
+ }
+ if (obj instanceof Provider) {
+ if (debug != null) {
+ debug.println("Loaded provider " + obj);
+ }
+ return (Provider)obj;
+ } else {
+ if (debug != null) {
+ debug.println(className + " is not a provider");
+ }
+ disableLoad();
+ return null;
+ }
+ }
+
/**
* Perform property expansion of the provider value.
*
diff --git a/ojluni/src/main/java/sun/security/jca/Providers.java b/ojluni/src/main/java/sun/security/jca/Providers.java
index d66d4f8..2212dc2 100755
--- a/ojluni/src/main/java/sun/security/jca/Providers.java
+++ b/ojluni/src/main/java/sun/security/jca/Providers.java
@@ -56,6 +56,15 @@
// triggers a getInstance() call (although that should not happen)
providerList = ProviderList.EMPTY;
providerList = ProviderList.fromSecurityProperties();
+
+ // removeInvalid is specified to try initializing all configured providers
+ // and removing those that aren't instantiable. This has the side effect
+ // of eagerly initializing all providers.
+ final int numConfiguredProviders = providerList.size();
+ providerList = providerList.removeInvalid();
+ if (numConfiguredProviders != providerList.size()) {
+ throw new AssertionError("Unable to configure default providers");
+ }
}
private Providers() {