You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ay...@apache.org on 2007/03/01 16:19:37 UTC
svn commit: r513381 -
/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/URLClassLoader.java
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<URL> invalidUrls = new HashSet<URL>();
+ Set<URL> invalidUrls = Collections.synchronizedSet(new HashSet<URL>());
- private IdentityHashMap<URL, JarFile> resCache = new IdentityHashMap<URL, JarFile>(
- 32);
+ private Map<URL, JarFile> resCache =
+ Collections.synchronizedMap(new IdentityHashMap<URL, JarFile>(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$