Mike,

Thanks for responding so promptly.  I certainly did not expect my fix to be the 
best one; I was just happy to find something that worked.  I couldn't think of 
a solution that didn't involve doPrivileged and HashMap knowing a lot about 
each other, like adding a HashMap option just for doPrivileged that skips the 
call from HashMap to doPrivileged. 

Tom


-----Original Message-----
From: Mike Duigou [mailto:mike.dui...@oracle.com] 
Sent: Monday, November 05, 2012 1:46 PM
To: Salter, Thomas A
Cc: core-libs-dev@openjdk.java.net
Subject: Re: HashMap / doPrivileged problem

Hello Thomas;

I am sorry to hear that you ran in to this problem. The class initialization 
order was something we found to be surprisingly brittle and tricky with this 
particular change. You've run across a path we didn't anticipate. I have 
created a bug for this issue : JDK-8002283 (It should be visible on 
bugs.sun.com soon).

On Nov 5 2012, at 07:02 , Salter, Thomas A wrote:

> I have encountered a problem with initializing the new HashMap code 
> introduced in Java 7u6.  I'm running with 7u9.  The problem only shows up 
> running rmid (sun.rmi.server.Activation).  It seems that the AccessController 
> needs to call HashMap but the new code in HashMap calls AccessController when 
> reading the property, jdk.map.althashing.threshold.
> 
> At the end of this message is the stack trace and the output of 
> -verbose:class showing the failure.
> 
> Here's a synopsis of what I think is happening:
> 1. AccessControllerContext at 98 caused Policy.isset.
> 2. Before calling isSet, the class loader initialize Policy by calling 
> <clinit>
> 3. Clinit found its way into HashMap init.
> 4. HashMap init called HashMap$Holder.<clinit>
> 5. Which called AccessController
> 6. Which eventually called isSet.   Policy was already loaded and its clinit 
> called, so isSet actually got called.
> 7. But Policy.<clinit> had not completed so policy is null, hence NPE.
> 8. The class loader from #2 caught the exception and wrapped it in the 
> ExceptionInitializationError.
> 
> I'm running a modified JDK, with modifications primarily in the area of file 
> and socket IO.  I'm pretty sure we've modified none of the classes in the 
> stack trace below.  The best I can tell, our changes eliminated the loading 
> of WinNTFileSystem and changed the CharSet classes that are called.  
> Apparently that code contains an incidental call to HashMap that gets it 
> initialized before doPrivileged gets called from some other class.
> 
> I've found an inelegant workaround.  In java.lang.System I added a "new 
> HashMap()" immediately following the call to set VM.booted to true.

I will see if there's an alternative way to accomplish this. There are several 
other classes that would need the same treatment for full safety and it seems 
unreasonable to just create throw-away instances to make sure they are 
initialized.

>  This causes the HashMap$Holder class to be initialized before doPrivileged 
> can call it.  The key to the fix is that HashMap needs to be called after 
> isBooted has been set so that it will invoke its Holder class.  Since the 
> Holder class invokes doPrivileged, the HashMap needs to have been initialized 
> before anyone calls doPrivileged.

Understood.

Thanks, 

Mike

Reply via email to