Recursive initialization of system class loader when initializing the security manager/provider
Sean Mullan
sean.mullan at oracle.com
Wed Mar 9 13:20:06 PST 2011
On 3/9/11 2:14 PM, Mandy Chung wrote:
> On 3/9/11 9:33 AM, Sean Mullan wrote:
>> How are you reproducing this? I did not encounter this when I was testing with
>> a SecurityManager a while back. Is this a recent change that caused this? Do
>> you have a test that I could run?
>
> I'll send you the test to reproduce this. This bootstrapping issue is not new
> and exists since the security provider was supported. It has been working since
> the recursive call to getSystemClassLoader returns null. During the system
> initialization time, it only loads the security providers on the bootclasspath
> (the default Sun provider) and fails to load other providers that are listed in
> the java.security configuration file if they cannot be found by the null boot
> class loader.
>
> In the jigsaw repo, it throws an InternalError instead when it recursively calls
> the getSystemClassLoader method:
>
> private static synchronized void initSystemClassLoader() {
> if (sclSet)
> return;
> if (initDepth> 0 || scl != null) {
> // Java object locks are re-entrant!
> throw new InternalError("Recursive initialization"
> + " of system class loader");
> }
> initDepth++;
> .....
>
>
> The point I want to raise here is not whether we should rollback the
> initSystemClassLoader to behave as in JDK 7 (return null if it's a recursive
> call). I think that we should avoid this recursive initialization if possible
> during system initialization.
Ok, this test is actually using a custom SecurityManager (not on the
bootclasspath) and that is triggering the exception. We have actually already
addressed this recursion issue in the JDK code. If you look at the code for
java.lang.SecurityManager.setSecurityManager0 you will see that we have to check
if the ProtectionDomain for a custom SecurityManager that is not on the
bootclasspath has been granted AllPermission before we allow it to be used. Now,
this requires System.getClassLoader to be invoked twice: the first time the
system-wide Launcher object is instantiated, which then triggers the second
invocation via ProviderConfig. But the second time through, the Launcher has
already been created (or in the process of being created) so the recursion stops
and everything works.
We can't lazily load a custom SecurityManager. You want that established as
early as possible. Do you know the reason we changed the code from JDK 7?
--Sean
>
> Mandy
>
>>
>> --Sean
>>
>> On 3/8/11 7:04 PM, Mandy Chung wrote:
>>> (Resending... I am not sure if the email I sent last night was delivered:
>>> http://mail.openjdk.java.net/pipermail/jigsaw-dev/2011-March/001186.html)
>>>
>>> Sean,
>>>
>>> There is a bootstrapping issue during the initialization of system class
>>> loader and the initialization of the security manager and security
>>> provider. The sun.security.jca.ProviderConfig class relies on the
>>> fact that ClassLoader.getSystemClassLoader() to return null if
>>> it's called recursively during the system class loader initialization
>>> or it throws IllegalStateException if "java.system.class.loader" is set.
>>>
>>> The stack trace below shows how it gets to the recursive initialization of
>>> the system class loader from the jigsaw legacy image build. This happens when
>>> sun.security.jca.ProviderConfig attempts to load the security provider
>>> listed in the java.security configuration. Since a security provider
>>> may be installed in the extension directory or possibly the class path,
>>> ProviderConfig class calls ClassLoader.getSystemClassLoader() as
>>> it uses the system class loader to find the specified security provider class.
>>> However, this is during the process of initializing the system class
>>> loader. This bootstrapping issue exists in the current JDK code base.
>>> In jdk 7 (and older jdk release) implementation,
>>> ClassLoader.getSystemClassLoader()
>>> returns null. In jigsaw, there was a change to throw InternalError
>>> when there is a recursive call to getSystemClassLoader. Regardless of
>>> whether the change in jigsaw java.lang.ClassLoader is valid, I wonder if
>>> there is a clean way to handle this bootstrapping issue (e.g.
>>> lazily initialize the security provider after the system class loader
>>> is initialized??). I think we should revisit this in jigsaw.
>>>
>>> Any thought?
>>>
>>> Mandy
>>>
>>> ---------------------------
>>> Error occurred during initialization of VM
>>> java.lang.InternalError: Recursive initialization of system class loader
>>> at java.lang.ClassLoader.initSystemClassLoader(ClassLoader.java:1522)
>>> at java.lang.ClassLoader.getSystemClassLoader(ClassLoader.java:1501)
>>> at sun.security.jca.ProviderConfig$2.run(ProviderConfig.java:212)
>>> at sun.security.jca.ProviderConfig$2.run(ProviderConfig.java:206)
>>> at java.security.AccessController.doPrivileged(Native Method)
>>> at sun.security.jca.ProviderConfig.doLoadProvider(ProviderConfig.java:206)
>>> at sun.security.jca.ProviderConfig.getProvider(ProviderConfig.java:187)
>>> at sun.security.jca.ProviderList.getProvider(ProviderList.java:232)
>>> at sun.security.jca.ProviderList.getService(ProviderList.java:330)
>>> at sun.security.jca.GetInstance.getInstance(GetInstance.java:157)
>>> at java.security.Security.getImpl(Security.java:696)
>>> at java.security.KeyStore.getInstance(KeyStore.java:602)
>>> at sun.security.util.PolicyUtil.getKeyStore(PolicyUtil.java:107)
>>> at sun.security.provider.PolicyFile.init(PolicyFile.java:635)
>>> at sun.security.provider.PolicyFile.access$400(PolicyFile.java:283)
>>> at sun.security.provider.PolicyFile$3.run(PolicyFile.java:547)
>>> at sun.security.provider.PolicyFile$3.run(PolicyFile.java:521)
>>> at java.security.AccessController.doPrivileged(Native Method)
>>> at sun.security.provider.PolicyFile.initPolicyFile(PolicyFile.java:520)
>>> at sun.security.provider.PolicyFile.initPolicyFile(PolicyFile.java:506)
>>> at sun.security.provider.PolicyFile.init(PolicyFile.java:465)
>>> at sun.security.provider.PolicyFile.<init>(PolicyFile.java:323)
>>> at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
>>> at
>>> sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
>>>
>>>
>>> at
>>> sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
>>>
>>>
>>> at java.lang.reflect.Constructor.newInstance(Constructor.java:530)
>>> at java.lang.Class.newInstance0(Class.java:374)
>>> at java.lang.Class.newInstance(Class.java:327)
>>> at java.security.Policy.getPolicyNoCheck(Policy.java:178)
>>> at java.security.ProtectionDomain.implies(ProtectionDomain.java:240)
>>> at java.lang.System$1.run(System.java:311)
>>> at java.security.AccessController.doPrivileged(Native Method)
>>> at java.lang.System.setSecurityManager0(System.java:309)
>>> at java.lang.System.setSecurityManager(System.java:287)
>>> at sun.misc.Launcher.<init>(Launcher.java:105)
>>> at sun.misc.Launcher.<clinit>(Launcher.java:58)
>>> at java.lang.ClassLoader.initLegacySystemClassLoader(ClassLoader.java:1539)
>>> at java.lang.ClassLoader.initSystemClassLoader(ClassLoader.java:1531)
>>> at java.lang.ClassLoader.getSystemClassLoader(ClassLoader.java:1501)
>>>
>
More information about the jigsaw-dev
mailing list