# HG changeset patch # User chegar # Date 1363790360 0 # Node ID 272ad530ce3ae71cf357380c0631167e1133c8f1 # Parent 43315ae7fa96faee40547dc33756752db710d1db 8010282: sun.net.www.protocol.jar.JarFileFactory.close(JarFile) should be thread-safe Reviewed-by: khazra, alanb diff -r 43315ae7fa96 -r 272ad530ce3a jdk/src/share/classes/sun/net/www/protocol/jar/JarURLConnection.java --- a/jdk/src/share/classes/sun/net/www/protocol/jar/JarURLConnection.java Wed Mar 20 13:21:53 2013 +0400 +++ b/jdk/src/share/classes/sun/net/www/protocol/jar/JarURLConnection.java Wed Mar 20 14:39:20 2013 +0000 @@ -51,7 +51,7 @@ /* the Jar file factory. It handles both retrieval and caching. */ - private static JarFileFactory factory = new JarFileFactory(); + private static final JarFileFactory factory = JarFileFactory.getInstance(); /* the url for the Jar file */ private URL jarFileURL; diff -r 43315ae7fa96 -r 272ad530ce3a jdk/src/solaris/classes/sun/net/www/protocol/jar/JarFileFactory.java --- a/jdk/src/solaris/classes/sun/net/www/protocol/jar/JarFileFactory.java Wed Mar 20 13:21:53 2013 +0400 +++ b/jdk/src/solaris/classes/sun/net/www/protocol/jar/JarFileFactory.java Wed Mar 20 14:39:20 2013 +0000 @@ -43,13 +43,24 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { /* the url to file cache */ - private static HashMap fileCache = new HashMap(); + private static final HashMap fileCache = new HashMap<>(); /* the file to url cache */ - private static HashMap urlCache = new HashMap(); + private static final HashMap urlCache = new HashMap<>(); + + private static final JarFileFactory instance = new JarFileFactory(); + + private JarFileFactory() { } + + public static JarFileFactory getInstance() { + return instance; + } URLConnection getConnection(JarFile jarFile) throws IOException { - URL u = urlCache.get(jarFile); + URL u; + synchronized (instance) { + u = urlCache.get(jarFile); + } if (u != null) return u.openConnection(); @@ -62,16 +73,16 @@ JarFile get(URL url, boolean useCaches) throws IOException { - JarFile result = null; - JarFile local_result = null; + JarFile result; + JarFile local_result; if (useCaches) { - synchronized (this) { + synchronized (instance) { result = getCachedJarFile(url); } if (result == null) { local_result = URLJarFile.getJarFile(url, this); - synchronized (this) { + synchronized (instance) { result = getCachedJarFile(url); if (result == null) { fileCache.put(URLUtil.urlNoFragString(url), local_result); @@ -99,14 +110,15 @@ * remove the JarFile from the cache */ public void close(JarFile jarFile) { - URL urlRemoved = urlCache.remove(jarFile); - if( urlRemoved != null) { + synchronized (instance) { + URL urlRemoved = urlCache.remove(jarFile); + if (urlRemoved != null) fileCache.remove(URLUtil.urlNoFragString(urlRemoved)); } } - private JarFile getCachedJarFile(URL url) { + assert Thread.holdsLock(instance); JarFile result = fileCache.get(URLUtil.urlNoFragString(url)); /* if the JAR file is cached, the permission will always be there */ diff -r 43315ae7fa96 -r 272ad530ce3a jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java --- a/jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java Wed Mar 20 13:21:53 2013 +0400 +++ b/jdk/src/windows/classes/sun/net/www/protocol/jar/JarFileFactory.java Wed Mar 20 14:39:20 2013 +0000 @@ -43,13 +43,24 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController { /* the url to file cache */ - private static HashMap fileCache = new HashMap(); + private static final HashMap fileCache = new HashMap<>(); /* the file to url cache */ - private static HashMap urlCache = new HashMap(); + private static final HashMap urlCache = new HashMap<>(); + + private static final JarFileFactory instance = new JarFileFactory(); + + private JarFileFactory() { } + + public static JarFileFactory getInstance() { + return instance; + } URLConnection getConnection(JarFile jarFile) throws IOException { - URL u = urlCache.get(jarFile); + URL u; + synchronized (instance) { + u = urlCache.get(jarFile); + } if (u != null) return u.openConnection(); @@ -72,16 +83,16 @@ } } - JarFile result = null; - JarFile local_result = null; + JarFile result; + JarFile local_result; if (useCaches) { - synchronized (this) { + synchronized (instance) { result = getCachedJarFile(url); } if (result == null) { local_result = URLJarFile.getJarFile(url, this); - synchronized (this) { + synchronized (instance) { result = getCachedJarFile(url); if (result == null) { fileCache.put(URLUtil.urlNoFragString(url), local_result); @@ -109,13 +120,15 @@ * remove the JarFile from the cache */ public void close(JarFile jarFile) { - URL urlRemoved = urlCache.remove(jarFile); - if( urlRemoved != null) { + synchronized (instance) { + URL urlRemoved = urlCache.remove(jarFile); + if (urlRemoved != null) fileCache.remove(URLUtil.urlNoFragString(urlRemoved)); } } private JarFile getCachedJarFile(URL url) { + assert Thread.holdsLock(instance); JarFile result = fileCache.get(URLUtil.urlNoFragString(url)); /* if the JAR file is cached, the permission will always be there */