mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Add JarFile caching
Cache root jar files in the Handler and also store nested jar files in the JarEntryData. See gh-1119
This commit is contained in:
parent
88195292dd
commit
a8777eda76
@ -18,11 +18,14 @@ package org.springframework.boot.loader.jar;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ -55,6 +58,11 @@ public class Handler extends URLStreamHandler {
|
||||
OPEN_CONNECTION_METHOD = method;
|
||||
}
|
||||
|
||||
private static SoftReference<Map<File, JarFile>> rootFileCache;
|
||||
static {
|
||||
rootFileCache = new SoftReference<Map<File, JarFile>>(null);
|
||||
}
|
||||
|
||||
private final Logger logger = Logger.getLogger(getClass().getName());
|
||||
|
||||
private final JarFile jarFile;
|
||||
@ -153,7 +161,14 @@ public class Handler extends URLStreamHandler {
|
||||
throw new IllegalStateException("Not a file URL");
|
||||
}
|
||||
String path = name.substring(FILE_PROTOCOL.length());
|
||||
return new JarFile(new File(path));
|
||||
File file = new File(path);
|
||||
Map<File, JarFile> cache = rootFileCache.get();
|
||||
JarFile jarFile = (cache == null ? null : cache.get(file));
|
||||
if (jarFile == null) {
|
||||
jarFile = new JarFile(file);
|
||||
addToRootFileCache(file, jarFile);
|
||||
}
|
||||
return jarFile;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IOException("Unable to open root Jar file '" + name + "'", ex);
|
||||
@ -168,4 +183,19 @@ public class Handler extends URLStreamHandler {
|
||||
}
|
||||
return jarFile.getNestedJarFile(jarEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given {@link JarFile} to the root file cache.
|
||||
* @param sourceFile the source file to add
|
||||
* @param jarFile the jar file.
|
||||
*/
|
||||
static void addToRootFileCache(File sourceFile, JarFile jarFile) {
|
||||
Map<File, JarFile> cache = rootFileCache.get();
|
||||
if (cache == null) {
|
||||
cache = new ConcurrentHashMap<File, JarFile>();
|
||||
rootFileCache = new SoftReference<Map<File, JarFile>>(cache);
|
||||
}
|
||||
cache.put(sourceFile, jarFile);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -53,6 +53,8 @@ public final class JarEntryData {
|
||||
|
||||
private SoftReference<JarEntry> entry;
|
||||
|
||||
JarFile nestedJar;
|
||||
|
||||
public JarEntryData(JarFile source, byte[] header, InputStream inputStream)
|
||||
throws IOException {
|
||||
this.source = source;
|
||||
|
@ -322,13 +322,13 @@ public class JarFile extends java.util.jar.JarFile implements Iterable<JarEntryD
|
||||
* @return a {@link JarFile} for the entry
|
||||
* @throws IOException
|
||||
*/
|
||||
public synchronized JarFile getNestedJarFile(final JarEntryData sourceEntry)
|
||||
public synchronized JarFile getNestedJarFile(JarEntryData sourceEntry)
|
||||
throws IOException {
|
||||
try {
|
||||
if (sourceEntry.isDirectory()) {
|
||||
return getNestedJarFileFromDirectoryEntry(sourceEntry);
|
||||
if (sourceEntry.nestedJar == null) {
|
||||
sourceEntry.nestedJar = createJarFileFromEntry(sourceEntry);
|
||||
}
|
||||
return getNestedJarFileFromFileEntry(sourceEntry);
|
||||
return sourceEntry.nestedJar;
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IOException("Unable to open nested jar file '"
|
||||
@ -336,7 +336,14 @@ public class JarFile extends java.util.jar.JarFile implements Iterable<JarEntryD
|
||||
}
|
||||
}
|
||||
|
||||
private JarFile getNestedJarFileFromDirectoryEntry(JarEntryData sourceEntry)
|
||||
private JarFile createJarFileFromEntry(JarEntryData sourceEntry) throws IOException {
|
||||
if (sourceEntry.isDirectory()) {
|
||||
return createJarFileFromDirectoryEntry(sourceEntry);
|
||||
}
|
||||
return createJarFileFromFileEntry(sourceEntry);
|
||||
}
|
||||
|
||||
private JarFile createJarFileFromDirectoryEntry(JarEntryData sourceEntry)
|
||||
throws IOException {
|
||||
final AsciiBytes sourceName = sourceEntry.getName();
|
||||
JarEntryFilter filter = new JarEntryFilter() {
|
||||
@ -353,7 +360,7 @@ public class JarFile extends java.util.jar.JarFile implements Iterable<JarEntryD
|
||||
this.entries, filter);
|
||||
}
|
||||
|
||||
private JarFile getNestedJarFileFromFileEntry(JarEntryData sourceEntry)
|
||||
private JarFile createJarFileFromFileEntry(JarEntryData sourceEntry)
|
||||
throws IOException {
|
||||
if (sourceEntry.getMethod() != ZipEntry.STORED) {
|
||||
throw new IllegalStateException("Unable to open nested compressed entry "
|
||||
|
Loading…
Reference in New Issue
Block a user