in com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaHotCodeReplaceProvider.java [354:415]
private String doHotCodeReplace(List<IResource> resourcesToReplace, List<String> qualifiedNamesToReplace) {
if (context == null || currentDebugSession == null) {
return null;
}
if (resourcesToReplace == null || qualifiedNamesToReplace == null || qualifiedNamesToReplace.isEmpty()
|| resourcesToReplace.isEmpty()) {
return null;
}
filterNotLoadedTypes(resourcesToReplace, qualifiedNamesToReplace);
if (qualifiedNamesToReplace.isEmpty()) {
return null;
// If none of the changed types are loaded, do nothing.
}
// Not supported scenario:
if (!currentDebugSession.getVM().canRedefineClasses()) {
publishEvent(HotCodeReplaceEvent.EventType.ERROR, "JVM doesn't support hot reload classes");
return "JVM doesn't support hot reload classes";
}
String errorMessage = null;
publishEvent(HotCodeReplaceEvent.EventType.STARTING, "Start hot code replacement procedure...");
try {
List<ThreadReference> poppedThreads = new ArrayList<>();
boolean framesPopped = false;
if (this.currentDebugSession.getVM().canPopFrames()) {
try {
attemptPopFrames(resourcesToReplace, qualifiedNamesToReplace, poppedThreads);
framesPopped = true; // No exception occurred
} catch (DebugException e) {
logger.log(Level.WARNING, "Failed to pop frames " + e.getMessage(), e);
}
}
redefineTypesJDK(resourcesToReplace, qualifiedNamesToReplace);
for (Consumer<List<String>> consumer : consumers) {
consumer.accept(qualifiedNamesToReplace);
}
if (containsObsoleteMethods()) {
publishEvent(HotCodeReplaceEvent.EventType.ERROR, "JVM contains obsolete methods");
errorMessage = "JVM contains obsolete methods";
}
if (currentDebugSession.getVM().canPopFrames() && framesPopped) {
attemptStepIn(poppedThreads);
} else {
attemptDropToFrame(resourcesToReplace, qualifiedNamesToReplace);
}
} catch (DebugException e) {
logger.log(Level.SEVERE, "Failed to complete hot code replace: " + e.getMessage(), e);
errorMessage = e.getMessage();
} finally {
publishEvent(HotCodeReplaceEvent.EventType.END, "Completed hot code replace", qualifiedNamesToReplace);
threadFrameMap.clear();
}
return errorMessage;
}