in common/src/main/java/com/alibaba/nacos/common/packagescan/resource/PathMatchingResourcePatternResolver.java [587:660]
protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource, URL rootDirUrl, String subPattern)
throws IOException {
URLConnection con = rootDirUrl.openConnection();
JarFile jarFile;
String jarFileUrl;
String rootEntryPath;
boolean closeJarFile;
if (con instanceof JarURLConnection) {
// Should usually be the case for traditional JAR files.
JarURLConnection jarCon = (JarURLConnection) con;
ResourceUtils.useCachesIfNecessary(jarCon);
jarFile = jarCon.getJarFile();
jarFileUrl = jarCon.getJarFileURL().toExternalForm();
JarEntry jarEntry = jarCon.getJarEntry();
rootEntryPath = (jarEntry != null ? jarEntry.getName() : "");
closeJarFile = !jarCon.getUseCaches();
} else {
// No JarURLConnection -> need to resort to URL file parsing.
// We'll assume URLs of the format "jar:path!/entry", with the protocol
// being arbitrary as long as following the entry format.
// We'll also handle paths with and without leading "file:" prefix.
String urlFile = rootDirUrl.getFile();
try {
int separatorIndex = urlFile.indexOf(ResourceUtils.WAR_URL_SEPARATOR);
if (separatorIndex == -1) {
separatorIndex = urlFile.indexOf(ResourceUtils.JAR_URL_SEPARATOR);
}
if (separatorIndex != -1) {
jarFileUrl = urlFile.substring(0, separatorIndex);
rootEntryPath = urlFile.substring(separatorIndex + 2); // both separators are 2 chars
jarFile = getJarFile(jarFileUrl);
} else {
jarFile = new JarFile(urlFile);
jarFileUrl = urlFile;
rootEntryPath = "";
}
closeJarFile = true;
} catch (ZipException ex) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Skipping invalid jar classpath entry [" + urlFile + "]");
}
return Collections.emptySet();
}
}
try {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Looking for matching resources in jar file [" + jarFileUrl + "]");
}
if (StringUtils.hasLength(rootEntryPath) && !rootEntryPath.endsWith("/")) {
// Root entry path must end with slash to allow for proper matching.
// The Sun JRE does not return a slash here, but BEA JRockit does.
rootEntryPath = rootEntryPath + "/";
}
Set<Resource> result = new LinkedHashSet<>(8);
for (Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements(); ) {
JarEntry entry = entries.nextElement();
String entryPath = entry.getName();
if (entryPath.startsWith(rootEntryPath)) {
String relativePath = entryPath.substring(rootEntryPath.length());
if (getPathMatcher().match(subPattern, relativePath)) {
result.add(rootDirResource.createRelative(relativePath));
}
}
}
return result;
} finally {
if (closeJarFile) {
jarFile.close();
}
}
}