mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8264048: Fix caching in Jar URL connections when an entry is missing
Co-authored-by: Daniel Fuchs <dfuchs@openjdk.org> Reviewed-by: bchristi, dfuchs
This commit is contained in:
parent
bf26a2558f
commit
a611c462f9
6 changed files with 371 additions and 27 deletions
|
@ -71,6 +71,75 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController {
|
|||
return get(url, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create a {@code JarFile} for the given {@code url}.
|
||||
* If {@code useCaches} is true, this method attempts to find
|
||||
* a jar file in the cache, and if so, returns it.
|
||||
* If no jar file is found in the cache, or {@code useCaches}
|
||||
* is false, the method creates a new jar file.
|
||||
* If the URL points to a local file, the returned jar file
|
||||
* will not be put in the cache yet.
|
||||
* The caller should then call {@link #cacheIfAbsent(URL, JarFile)}
|
||||
* with the returned jar file, if updating the cache is desired.
|
||||
* @param url the jar file url
|
||||
* @param useCaches whether the cache should be used
|
||||
* @return a new or cached jar file.
|
||||
* @throws IOException if the jar file couldn't be created
|
||||
*/
|
||||
JarFile getOrCreate(URL url, boolean useCaches) throws IOException {
|
||||
if (useCaches == false) {
|
||||
return get(url, false);
|
||||
}
|
||||
|
||||
if (!URLJarFile.isFileURL(url)) {
|
||||
// A temporary file will be created, we can prepopulate
|
||||
// the cache in this case.
|
||||
return get(url, useCaches);
|
||||
}
|
||||
|
||||
// We have a local file. Do not prepopulate the cache.
|
||||
JarFile result;
|
||||
synchronized (instance) {
|
||||
result = getCachedJarFile(url);
|
||||
}
|
||||
if (result == null) {
|
||||
result = URLJarFile.getJarFile(url, this);
|
||||
}
|
||||
if (result == null)
|
||||
throw new FileNotFoundException(url.toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the given jar file if it isn't present in the cache.
|
||||
* Otherwise, does nothing.
|
||||
* @param url the jar file URL
|
||||
* @param jarFile the jar file to close
|
||||
* @return true if the jar file has been closed, false otherwise.
|
||||
* @throws IOException if an error occurs while closing the jar file.
|
||||
*/
|
||||
boolean closeIfNotCached(URL url, JarFile jarFile) throws IOException {
|
||||
JarFile result;
|
||||
synchronized (instance) {
|
||||
result = getCachedJarFile(url);
|
||||
}
|
||||
if (result != jarFile) jarFile.close();
|
||||
return result != jarFile;
|
||||
}
|
||||
|
||||
boolean cacheIfAbsent(URL url, JarFile jarFile) {
|
||||
JarFile cached;
|
||||
synchronized (instance) {
|
||||
String key = urlKey(url);
|
||||
cached = fileCache.get(key);
|
||||
if (cached == null) {
|
||||
fileCache.put(key, jarFile);
|
||||
urlCache.put(jarFile, url);
|
||||
}
|
||||
}
|
||||
return cached == null || cached == jarFile;
|
||||
}
|
||||
|
||||
JarFile get(URL url, boolean useCaches) throws IOException {
|
||||
|
||||
JarFile result;
|
||||
|
@ -106,7 +175,7 @@ class JarFileFactory implements URLJarFile.URLJarFileCloseController {
|
|||
|
||||
/**
|
||||
* Callback method of the URLJarFileCloseController to
|
||||
* indicate that the JarFile is close. This way we can
|
||||
* indicate that the JarFile is closed. This way we can
|
||||
* remove the JarFile from the cache
|
||||
*/
|
||||
public void close(JarFile jarFile) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue