in core/src/main/java/com/spotify/missinglink/ArtifactLoader.java [87:138]
private Collection<JarEntry> getClassesForCurrentJavaVersion(Iterable<JarEntry> entries) {
// First categorize all the found class files by their target JVM
// classFilesPerJavaVersion: target JVM version -> normalized full name -> JarEntry
SortedMap<Integer, Map<String, JarEntry>> classFilesPerJavaVersion = new TreeMap<>();
String patternString = "META-INF/versions/(\\d+)/";
Pattern pattern = Pattern.compile(patternString);
for (JarEntry entry : entries) {
String fileFullName = entry.getName();
if (fileFullName.endsWith(".class")) {
Matcher m = pattern.matcher(fileFullName);
if (m.find()) {
Integer targetJavaVersion = Integer.parseInt(m.group(1));
String normalizedFileFullName = fileFullName.replaceAll(patternString, "");
if (!classFilesPerJavaVersion.containsKey(targetJavaVersion)) {
classFilesPerJavaVersion.put(targetJavaVersion, new HashMap<>());
}
classFilesPerJavaVersion.get(targetJavaVersion).put(normalizedFileFullName, entry);
} else {
Integer withoutVersion = 0;
if (!classFilesPerJavaVersion.containsKey(withoutVersion)) {
classFilesPerJavaVersion.put(withoutVersion, new HashMap<>());
}
classFilesPerJavaVersion.get(withoutVersion).put(fileFullName, entry);
}
}
}
// We have to figure out what JVM version we're running on.
Integer currentJavaVersion;
String[] javaVersionElements =
System.getProperty("java.version").replaceAll("\\-ea", "").split("\\.");
if (javaVersionElements[0].equals("1")) {
currentJavaVersion = Integer.parseInt(javaVersionElements[1]);
} else {
currentJavaVersion = Integer.parseInt(javaVersionElements[0]);
}
// Start layering the class files from old JVM version to new and thus effectively override the
// old files by the new ones.
Map<String, JarEntry> selectedClassFiles = new HashMap<>();
for (Map.Entry<Integer, Map<String, JarEntry>> entry : classFilesPerJavaVersion.entrySet()) {
Integer targetJavaVersion = entry.getKey();
if (targetJavaVersion > currentJavaVersion) {
break;
}
Map<String, JarEntry> pathToClassfile = entry.getValue();
selectedClassFiles.putAll(pathToClassfile);
}
return selectedClassFiles.values();
}