recent code fix led me to look at this code in ServiceLoader:
```
private ServiceLoader(Class<?> caller, Class<S> svc, ClassLoader cl) {
Objects.requireNonNull(svc);
if (VM.isBooted()) {
checkCaller(caller, svc);
if (cl == null) {
cl = ClassLoader.getSystemClassLoader();
}
} else {
// if we get here then it means that ServiceLoader is being used
// before the VM initialization has completed. At this point then
// only code in the java.base should be executing.
Module callerModule = caller.getModule();
Module base = Object.class.getModule();
Module svcModule = svc.getModule();
if (callerModule != base || svcModule != base) {
fail(svc, "not accessible to " + callerModule + " during VM init");
}
// restricted to boot loader during startup
cl = null;
}
```
it sets `cl` to null if VM is not booted (and the 'loader' instance gets assigned same). Setting it to null seems to be an overloaded design here. It can mean that base modules are to be searched or that VM isn't booted (AFAICT)
Here's code from nextProviderClass() (with a comment inserted) :
```
private Class<?> nextProviderClass() {
....
....
if (loader == null) {
// loader set to null since !VM.isBooted in earlier check
// now, we're about to call getSystemClassLoader which throws IllegalStateException
configs = ClassLoader.getSystemResources(fullName); // getSystemClassLoader().getResources(fullName);
} else if (loader == ClassLoaders.platformClassLoader()) {
```
in this scenario, the VM isn't booted but we're about to call getSystemClassLoader(). Are we meant to avoid that as per ClassLoader impl note ?
'java.system.class.loader' is set in this test. Should we have a VM.isBooted() check here ?
Leading to this fail in not being able to load CLDR provider for a Date.toString() debug call being made (while VM is booting):
Caused by: java.lang.IllegalStateException: getSystemClassLoader cannot be called during the system class loader instantiation
at java.lang.ClassLoader.getSystemClassLoader(java.base@23-internal/ClassLoader.java:1952)
at java.lang.ClassLoader.getSystemResources(java.base@23-internal/ClassLoader.java:1723)
at java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(java.base@23-internal/ServiceLoader.java:1189)
at java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(java.base@23-internal/ServiceLoader.java:1224)
at java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(java.base@23-internal/ServiceLoader.java:1269)
at java.util.ServiceLoader$2.hasNext(java.base@23-internal/ServiceLoader.java:1305)
at java.util.ServiceLoader$3.hasNext(java.base@23-internal/ServiceLoader.java:1387)
at sun.util.cldr.CLDRLocaleProviderAdapter.lambda$new$0(java.base@23-internal/CLDRLocaleProviderAdapter.java:84)
at java.security.AccessController.doPrivileged(java.base@23-internal/AccessController.java:571)
at sun.util.cldr.CLDRLocaleProviderAdapter.<init>(java.base@23-internal/CLDRLocaleProviderAdapter.java:83)
at jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(java.base@23-internal/DirectConstructorHandleAccessor.java:62)
at java.lang.reflect.Constructor.newInstanceWithCaller(java.base@23-internal/Constructor.java:502)
at java.lang.reflect.Constructor.newInstance(java.base@23-internal/Constructor.java:486)
at sun.util.locale.provider.LocaleProviderAdapter.forType(java.base@23-internal/LocaleProviderAdapter.java:182)
at sun.util.locale.provider.LocaleServiceProviderPool.findProviders(java.base@23-internal/LocaleServiceProviderPool.java:311)
at sun.util.locale.provider.LocaleServiceProviderPool.getLocalizedObjectImpl(java.base@23-internal/LocaleServiceProviderPool.java:283)
at sun.util.locale.provider.LocaleServiceProviderPool.getLocalizedObject(java.base@23-internal/LocaleServiceProviderPool.java:245)
at sun.util.locale.provider.TimeZoneNameUtility.retrieveDisplayNamesImpl(java.base@23-internal/TimeZoneNameUtility.java:197)
at sun.util.locale.provider.TimeZoneNameUtility.retrieveDisplayName(java.base@23-internal/TimeZoneNameUtility.java:150)
at java.util.TimeZone.getDisplayName(java.base@23-internal/TimeZone.java:430)
at java.util.Date.toString(java.base@23-internal/Date.java:1045)
at java.lang.String.valueOf(java.base@23-internal/String.java:4509)
at java.lang.StringBuilder.append(java.base@23-internal/StringBuilder.java:173)
at sun.security.x509.CertificateValidity.toString(java.base@23-internal/CertificateValidity.java:118)
at java.lang.String.valueOf(java.base@23-internal/String.java:4509)
at java.lang.StringBuilder.append(java.base@23-internal/StringBuilder.java:173)
at sun.security.x509.X509CertInfo.toString(java.base@23-internal/X509CertInfo.java:221)
at java.lang.String.valueOf(java.base@23-internal/String.java:4509)
at java.lang.StringBuilder.append(java.base@23-internal/StringBuilder.java:173)
at sun.security.x509.X509CertImpl.toString(java.base@23-internal/X509CertImpl.java:560)
at java.lang.String.valueOf(java.base@23-internal/String.java:4509)
at java.lang.StringBuilder.append(java.base@23-internal/StringBuilder.java:173)
at sun.security.util.SignatureFileVerifier.getSigners(java.base@23-internal/SignatureFileVerifier.java:742)
at sun.security.util.SignatureFileVerifier.processImpl(java.base@23-internal/SignatureFileVerifier.java:312)
at sun.security.util.SignatureFileVerifier.process(java.base@23-internal/SignatureFileVerifier.java:281)
at java.util.jar.JarVerifier.processEntry(java.base@23-internal/JarVerifier.java:320)
at java.util.jar.JarVerifier.update(java.base@23-internal/JarVerifier.java:232)
at java.util.jar.JarFile.initializeVerifier(java.base@23-internal/JarFile.java:760)
at java.util.jar.JarFile.getInputStream(java.base@23-internal/JarFile.java:858)
at jdk.internal.loader.URLClassPath$JarLoader$2.getInputStream(java.base@23-internal/URLClassPath.java:837)
at jdk.internal.loader.Resource.cachedInputStream(java.base@23-internal/Resource.java:77)
at jdk.internal.loader.Resource.getByteBuffer(java.base@23-internal/Resource.java:163)
at jdk.internal.loader.BuiltinClassLoader.defineClass(java.base@23-internal/BuiltinClassLoader.java:853)
at jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(java.base@23-internal/BuiltinClassLoader.java:760)
at jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(java.base@23-internal/BuiltinClassLoader.java:681)
at jdk.internal.loader.BuiltinClassLoader.loadClass(java.base@23-internal/BuiltinClassLoader.java:639)
at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(java.base@23-internal/ClassLoaders.java:188)
at java.lang.ClassLoader.loadClass(java.base@23-internal/ClassLoader.java:528)
at java.lang.Class.forName0(java.base@23-internal/Native Method)
at java.lang.Class.forName(java.base@23-internal/Class.java:578)
at java.lang.Class.forName(java.base@23-internal/Class.java:557)
at java.lang.ClassLoader.initSystemClassLoader(java.base@23-internal/ClassLoader.java:1997)
at java.lang.System.initPhase3(java.base@23-internal/System.java:2338)
```
private ServiceLoader(Class<?> caller, Class<S> svc, ClassLoader cl) {
Objects.requireNonNull(svc);
if (VM.isBooted()) {
checkCaller(caller, svc);
if (cl == null) {
cl = ClassLoader.getSystemClassLoader();
}
} else {
// if we get here then it means that ServiceLoader is being used
// before the VM initialization has completed. At this point then
// only code in the java.base should be executing.
Module callerModule = caller.getModule();
Module base = Object.class.getModule();
Module svcModule = svc.getModule();
if (callerModule != base || svcModule != base) {
fail(svc, "not accessible to " + callerModule + " during VM init");
}
// restricted to boot loader during startup
cl = null;
}
```
it sets `cl` to null if VM is not booted (and the 'loader' instance gets assigned same). Setting it to null seems to be an overloaded design here. It can mean that base modules are to be searched or that VM isn't booted (AFAICT)
Here's code from nextProviderClass() (with a comment inserted) :
```
private Class<?> nextProviderClass() {
....
....
if (loader == null) {
// loader set to null since !VM.isBooted in earlier check
// now, we're about to call getSystemClassLoader which throws IllegalStateException
configs = ClassLoader.getSystemResources(fullName); // getSystemClassLoader().getResources(fullName);
} else if (loader == ClassLoaders.platformClassLoader()) {
```
in this scenario, the VM isn't booted but we're about to call getSystemClassLoader(). Are we meant to avoid that as per ClassLoader impl note ?
'java.system.class.loader' is set in this test. Should we have a VM.isBooted() check here ?
Leading to this fail in not being able to load CLDR provider for a Date.toString() debug call being made (while VM is booting):
Caused by: java.lang.IllegalStateException: getSystemClassLoader cannot be called during the system class loader instantiation
at java.lang.ClassLoader.getSystemClassLoader(java.base@23-internal/ClassLoader.java:1952)
at java.lang.ClassLoader.getSystemResources(java.base@23-internal/ClassLoader.java:1723)
at java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(java.base@23-internal/ServiceLoader.java:1189)
at java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(java.base@23-internal/ServiceLoader.java:1224)
at java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(java.base@23-internal/ServiceLoader.java:1269)
at java.util.ServiceLoader$2.hasNext(java.base@23-internal/ServiceLoader.java:1305)
at java.util.ServiceLoader$3.hasNext(java.base@23-internal/ServiceLoader.java:1387)
at sun.util.cldr.CLDRLocaleProviderAdapter.lambda$new$0(java.base@23-internal/CLDRLocaleProviderAdapter.java:84)
at java.security.AccessController.doPrivileged(java.base@23-internal/AccessController.java:571)
at sun.util.cldr.CLDRLocaleProviderAdapter.<init>(java.base@23-internal/CLDRLocaleProviderAdapter.java:83)
at jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(java.base@23-internal/DirectConstructorHandleAccessor.java:62)
at java.lang.reflect.Constructor.newInstanceWithCaller(java.base@23-internal/Constructor.java:502)
at java.lang.reflect.Constructor.newInstance(java.base@23-internal/Constructor.java:486)
at sun.util.locale.provider.LocaleProviderAdapter.forType(java.base@23-internal/LocaleProviderAdapter.java:182)
at sun.util.locale.provider.LocaleServiceProviderPool.findProviders(java.base@23-internal/LocaleServiceProviderPool.java:311)
at sun.util.locale.provider.LocaleServiceProviderPool.getLocalizedObjectImpl(java.base@23-internal/LocaleServiceProviderPool.java:283)
at sun.util.locale.provider.LocaleServiceProviderPool.getLocalizedObject(java.base@23-internal/LocaleServiceProviderPool.java:245)
at sun.util.locale.provider.TimeZoneNameUtility.retrieveDisplayNamesImpl(java.base@23-internal/TimeZoneNameUtility.java:197)
at sun.util.locale.provider.TimeZoneNameUtility.retrieveDisplayName(java.base@23-internal/TimeZoneNameUtility.java:150)
at java.util.TimeZone.getDisplayName(java.base@23-internal/TimeZone.java:430)
at java.util.Date.toString(java.base@23-internal/Date.java:1045)
at java.lang.String.valueOf(java.base@23-internal/String.java:4509)
at java.lang.StringBuilder.append(java.base@23-internal/StringBuilder.java:173)
at sun.security.x509.CertificateValidity.toString(java.base@23-internal/CertificateValidity.java:118)
at java.lang.String.valueOf(java.base@23-internal/String.java:4509)
at java.lang.StringBuilder.append(java.base@23-internal/StringBuilder.java:173)
at sun.security.x509.X509CertInfo.toString(java.base@23-internal/X509CertInfo.java:221)
at java.lang.String.valueOf(java.base@23-internal/String.java:4509)
at java.lang.StringBuilder.append(java.base@23-internal/StringBuilder.java:173)
at sun.security.x509.X509CertImpl.toString(java.base@23-internal/X509CertImpl.java:560)
at java.lang.String.valueOf(java.base@23-internal/String.java:4509)
at java.lang.StringBuilder.append(java.base@23-internal/StringBuilder.java:173)
at sun.security.util.SignatureFileVerifier.getSigners(java.base@23-internal/SignatureFileVerifier.java:742)
at sun.security.util.SignatureFileVerifier.processImpl(java.base@23-internal/SignatureFileVerifier.java:312)
at sun.security.util.SignatureFileVerifier.process(java.base@23-internal/SignatureFileVerifier.java:281)
at java.util.jar.JarVerifier.processEntry(java.base@23-internal/JarVerifier.java:320)
at java.util.jar.JarVerifier.update(java.base@23-internal/JarVerifier.java:232)
at java.util.jar.JarFile.initializeVerifier(java.base@23-internal/JarFile.java:760)
at java.util.jar.JarFile.getInputStream(java.base@23-internal/JarFile.java:858)
at jdk.internal.loader.URLClassPath$JarLoader$2.getInputStream(java.base@23-internal/URLClassPath.java:837)
at jdk.internal.loader.Resource.cachedInputStream(java.base@23-internal/Resource.java:77)
at jdk.internal.loader.Resource.getByteBuffer(java.base@23-internal/Resource.java:163)
at jdk.internal.loader.BuiltinClassLoader.defineClass(java.base@23-internal/BuiltinClassLoader.java:853)
at jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(java.base@23-internal/BuiltinClassLoader.java:760)
at jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(java.base@23-internal/BuiltinClassLoader.java:681)
at jdk.internal.loader.BuiltinClassLoader.loadClass(java.base@23-internal/BuiltinClassLoader.java:639)
at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(java.base@23-internal/ClassLoaders.java:188)
at java.lang.ClassLoader.loadClass(java.base@23-internal/ClassLoader.java:528)
at java.lang.Class.forName0(java.base@23-internal/Native Method)
at java.lang.Class.forName(java.base@23-internal/Class.java:578)
at java.lang.Class.forName(java.base@23-internal/Class.java:557)
at java.lang.ClassLoader.initSystemClassLoader(java.base@23-internal/ClassLoader.java:1997)
at java.lang.System.initPhase3(java.base@23-internal/System.java:2338)