Return-Path: Delivered-To: apmail-harmony-commits-archive@www.apache.org Received: (qmail 41511 invoked from network); 1 Mar 2007 15:20:00 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 1 Mar 2007 15:20:00 -0000 Received: (qmail 6303 invoked by uid 500); 1 Mar 2007 15:20:08 -0000 Delivered-To: apmail-harmony-commits-archive@harmony.apache.org Received: (qmail 6284 invoked by uid 500); 1 Mar 2007 15:20:08 -0000 Mailing-List: contact commits-help@harmony.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@harmony.apache.org Delivered-To: mailing list commits@harmony.apache.org Received: (qmail 6275 invoked by uid 99); 1 Mar 2007 15:20:07 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 01 Mar 2007 07:20:07 -0800 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 01 Mar 2007 07:19:58 -0800 Received: by eris.apache.org (Postfix, from userid 65534) id 25CF51A981A; Thu, 1 Mar 2007 07:19:38 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r513381 - /harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/URLClassLoader.java Date: Thu, 01 Mar 2007 15:19:37 -0000 To: commits@harmony.apache.org From: ayza@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070301151938.25CF51A981A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: ayza Date: Thu Mar 1 07:19:37 2007 New Revision: 513381 URL: http://svn.apache.org/viewvc?view=rev&rev=513381 Log: Applying patch from HARMONY-2982 ([classlib][net] java.net.URLClassLoader implementation is not thread safe.). Thread issues should be fixed now. Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/URLClassLoader.java Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/URLClassLoader.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/URLClassLoader.java?view=diff&rev=513381&r1=513380&r2=513381 ============================================================================== --- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/URLClassLoader.java (original) +++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/URLClassLoader.java Thu Mar 1 07:19:37 2007 @@ -31,6 +31,7 @@ import java.security.SecureClassLoader; import java.security.cert.Certificate; import java.util.ArrayList; +import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; @@ -38,6 +39,8 @@ import java.util.IdentityHashMap; import java.util.List; import java.util.ListIterator; +import java.util.Map; +import java.util.Set; import java.util.StringTokenizer; import java.util.Vector; import java.util.jar.Attributes; @@ -66,10 +69,12 @@ URL[] urls, orgUrls; - HashSet invalidUrls = new HashSet(); + Set invalidUrls = Collections.synchronizedSet(new HashSet()); - private IdentityHashMap resCache = new IdentityHashMap( - 32); + private Map resCache = + Collections.synchronizedMap(new IdentityHashMap(32)); + + private Object lock = new Object(); private URLStreamHandlerFactory factory; @@ -170,7 +175,9 @@ URL search = createSearchURL(url); urls = addURL(urls, search); orgUrls = addURL(orgUrls, url); - extensions.put(search, null); + synchronized (extensions) { + extensions.put(search, null); + } } catch (MalformedURLException e) { } } @@ -704,24 +711,36 @@ String protocol = currentUrl.getProtocol(); if (protocol.equals("jar")) { //$NON-NLS-1$ jf = resCache.get(currentUrl); - if (jf == null) { - /* - * If the connection for currentUrl or resURL is - * used, getJarFile() will throw an exception if the - * entry doesn't exist. - */ - URL jarURL = ((JarURLConnection) currentUrl - .openConnection()).getJarFileURL(); - try { - JarURLConnection juc = (JarURLConnection) new URL( - "jar", "", //$NON-NLS-1$ //$NON-NLS-2$ - jarURL.toExternalForm() + "!/").openConnection(); //$NON-NLS-1$ - jf = juc.getJarFile(); - resCache.put(currentUrl, jf); - } catch (IOException e) { - // Don't look for this jar file again - invalidUrls.add(searchList[i]); - throw e; + if ((jf == null) && (!invalidUrls.contains(currentUrl))) { + // each jf should be found only once + // so we do this job in the synchronized block + synchronized (lock) { + // Check the cache again in case another thread + // updated it while we're waiting on lock + jf = resCache.get(currentUrl); + if (jf == null) { + if (invalidUrls.contains(currentUrl)) { + continue; + } + /* + * If the connection for currentUrl or resURL is + * used, getJarFile() will throw an exception if the + * entry doesn't exist. + */ + URL jarURL = ((JarURLConnection) currentUrl + .openConnection()).getJarFileURL(); + try { + JarURLConnection juc = (JarURLConnection) new URL( + "jar", "", //$NON-NLS-1$ //$NON-NLS-2$ + jarURL.toExternalForm() + "!/").openConnection(); //$NON-NLS-1$ + jf = juc.getJarFile(); + resCache.put(currentUrl, jf); + } catch (IOException e) { + // Don't look for this jar file again + invalidUrls.add(searchList[i]); + throw e; + } + } } } String entryName; @@ -931,9 +950,11 @@ try { URL newURL = new URL(protocol, host, port, file + element + "!/"); //$NON-NLS-1$ - if (!extensions.containsKey(newURL)) { - extensions.put(newURL, null); - addedURLs.add(newURL); + synchronized (extensions) { + if (!extensions.containsKey(newURL)) { + extensions.put(newURL, null); + addedURLs.add(newURL); + } } } catch (MalformedURLException e) { // Nothing is added @@ -1014,22 +1035,32 @@ String protocol = thisURL.getProtocol(); if (protocol.equals("jar")) { //$NON-NLS-1$ jf = resCache.get(thisURL); - if (jf == null) { - // If the connection for testURL or thisURL is used, - // getJarFile() will throw an exception if the entry - // doesn't exist. - URL jarURL = ((JarURLConnection) thisURL - .openConnection()).getJarFileURL(); - try { - JarURLConnection juc = (JarURLConnection) new URL( - "jar", "", jarURL.toExternalForm() + "!/") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - .openConnection(); - jf = juc.getJarFile(); - resCache.put(thisURL, jf); - } catch (IOException e) { - // Don't look for this jar file again - invalidUrls.add(searchURLs[i]); - throw e; + if ((jf == null) && (!invalidUrls.contains(thisURL))) { + synchronized (lock) { + // Check the cache again in case another thread updated it + // updated it while we're waiting on lock + jf = resCache.get(thisURL); + if (jf == null) { + if (invalidUrls.contains(thisURL)) { + continue; + } + // If the connection for testURL or thisURL is used, + // getJarFile() will throw an exception if the entry + // doesn't exist. + URL jarURL = ((JarURLConnection) thisURL + .openConnection()).getJarFileURL(); + try { + JarURLConnection juc = (JarURLConnection) new URL( + "jar", "", jarURL.toExternalForm() + "!/") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + .openConnection(); + jf = juc.getJarFile(); + resCache.put(thisURL, jf); + } catch (IOException e) { + // Don't look for this jar file again + invalidUrls.add(searchURLs[i]); + throw e; + } + } } } if (thisURL.getFile().endsWith("!/")) { //$NON-NLS-1$