Skip to content

Commit f79664c

Browse files
Add debug/toolbar button to reload changed classes (#586)
* Add debug/toolbar button to reload changed classes Signed-off-by: Jinbo Wang <[email protected]> * Make tslint happy Signed-off-by: Jinbo Wang <[email protected]> * Show a warning when autobuild is disabled Signed-off-by: Jinbo Wang <[email protected]> * Address review comments Signed-off-by: Jinbo Wang <[email protected]>
1 parent 7af2ba9 commit f79664c

16 files changed

+120
-29
lines changed

Diff for: .vscodeignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ src/**
77
tsconfig.json
88
gulpfile.js
99
.gitignore
10-
images/**
10+
images/docs/**
1111
testprojects/**
1212
TestPlan.md
1313
.github/**

Diff for: README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,10 @@ Please also check the documentation of [Language Support for Java by Red Hat](ht
9595
- `java.debug.settings.showQualifiedNames`: show fully qualified class names in "Variables" viewlet, defaults to `false`.
9696
- `java.debug.settings.showLogicalStructure`: show the logical structure for the Collection and Map classes in "Variables" viewlet, defaults to `true`.
9797
- `java.debug.settings.maxStringLength`: the maximum length of string displayed in "Variables" or "Debug Console" viewlet, the string longer than this length will be trimmed, defaults to `0` which means no trim is performed.
98-
- `java.debug.settings.enableHotCodeReplace`: enable hot code replace for Java code. Make sure the auto build is not disabled for [VSCode Java](https://github.com/redhat-developer/vscode-java). See the [wiki page](https://github.com/Microsoft/vscode-java-debug/wiki/Hot-Code-Replace) for more information about usages and limitations.
98+
- `java.debug.settings.hotCodeReplace`: Reload the changed Java classes during debugging, defaults to `manual`. Make sure `java.autobuild.enabled` is not disabled for [VSCode Java](https://github.com/redhat-developer/vscode-java). See the [wiki page](https://github.com/Microsoft/vscode-java-debug/wiki/Hot-Code-Replace) for more information about usages and limitations.
99+
- manual - Click the toolbar to apply the changes.
100+
- auto - Automatically apply the changes after compilation.
101+
- never - Never apply the changes.
99102
- `java.debug.settings.enableRunDebugCodeLens`: enable the code lens provider for the run and debug buttons over main entry points, defaults to `true`.
100103
- `java.debug.settings.forceBuildBeforeLaunch`: force building the workspace before launching java program, defaults to `true`.
101104

Diff for: TestPlan.md

+24-11
Original file line numberDiff line numberDiff line change
@@ -299,20 +299,33 @@ anonymous
299299

300300
1. Open project `19.java9-app` in vscode.
301301
2. Follow gif to verify step filters feature.
302-
![stepfilter](images/33868694-673f14b0-df3f-11e7-9983-b3cff5842020.gif)
302+
![stepfilter](images/docs/33868694-673f14b0-df3f-11e7-9983-b3cff5842020.gif)
303303

304304
The new gif:
305-
![stepfilters](images/34507770-69597114-f074-11e7-8f32-027ad1d7a4fd.gif)
305+
![stepfilters](images/docs/34507770-69597114-f074-11e7-8f32-027ad1d7a4fd.gif)
306306

307307
## Hot Code Replace
308-
308+
- Manually trigger hot code replace
309309
1. Open project `24.hotCodeReplace` in vscode.
310-
2. Set breakpoints: NameProvider.java line 12; Person.java line 13
310+
2. Set breakpoints: NameProvider.java line 12; Person.java line 13.
311311
3. Press `F5` to start debug.
312-
4. The program stopped at the Person.java line 13
313-
5. Change the value of the line "old" to "new"
314-
5. Save the document to trigger HCR. Check the breakpoint will stop at line 12
315-
6. Click F10 to step over, check the value of `res` on the debug view of local variable which should be `new`
312+
4. The program stopped at the Person.java line 13.
313+
5. Change the value of the line "old" to "new", and save the document.
314+
6. Click the "Hot Code Replace" icon in the debug toolbar to trigger HCR. Check the breakpoint will stop at line 12 .
315+
7. Click F10 to step over, check the value of `res` on the debug view of local variable which should be `new`.
316+
317+
- Automatically trigger hot code replace
318+
1. Repeat step 1 ~ 4 above.
319+
2. Change `java.debug.settings.hotCodeReplace` to `auto`.
320+
3. Change the value of the line "old" to "new", and save the document.
321+
4. HCR will be automatically triggered. Check the breakpoint will stop at line 12 .
322+
5. Click F10 to step over, check the value of `res` on the debug view of local variable which should be `new`.
323+
324+
- Disable hot code replace
325+
1. Repeat step 1 ~ 4 above.
326+
2. Change `java.debug.settings.hotCodeReplace` to `never`.
327+
3. Change the value of the line "old" to "new", and save the document.
328+
4. Click F10 to step over, check the value of `res` on the debug view of local variable which should be `old`.
316329

317330
## Conditional Breakpoints
318331

@@ -342,7 +355,7 @@ public class App
342355

343356
2. set conditional breakpoint on line 13 with condition `i ==1000`, F5 and wait the breakpoint to be hit
344357

345-
![java-conditional-bp-demo](images/37269785-0ffef8e6-2607-11e8-955f-93548ad5a0ad.gif)
358+
![java-conditional-bp-demo](images/docs/37269785-0ffef8e6-2607-11e8-955f-93548ad5a0ad.gif)
346359

347360
3. verify i equals 1000 in variable window.
348361
4. F5 and wait for program to exit.
@@ -406,7 +419,7 @@ Exception in thread "main" java.lang.IllegalStateException
406419
2. Launch java debugger and continue your program.
407420
3. When the logpoint code branch is hit, it just log the message to the console and doesn't stop your program.
408421

409-
![logpoint](images/41949312-77627a40-79f3-11e8-9fd2-def4fa06e28d.gif)
422+
![logpoint](images/docs/41949312-77627a40-79f3-11e8-9fd2-def4fa06e28d.gif)
410423

411424

412425
## Start without debugging
@@ -472,7 +485,7 @@ Exception in thread "main" java.lang.IllegalStateException
472485
```
473486
4. Press F5 to verify the variables should be like this:
474487
475-
![args](images/args.PNG)
488+
![args](images/docs/args.PNG)
476489
477490
## Classpath shortener for long classpath project
478491
1. Open `longclasspath` project in VS Code.

Diff for: Troubleshooting.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ This error indicates you are doing `Hot Code Replace`. The `Hot Code Replace` fe
4545

4646
### Try:
4747
1. Restart your application to apply the new changes. Or ignore the message, and continue to debug.
48-
2. You can disable the hot code replace feature by changing the user setting `"java.debug.settings.enableHotCodeReplace": false`.
48+
2. You can disable the hot code replace feature by changing the user setting `"java.debug.settings.hotCodeReplace": "never"`.
4949

5050
## Please specify the host name and the port of the remote debuggee in the launch.json.
5151
### Reason:

Diff for: images/commands/hot_code_replace.svg

+13
Loading

Diff for: images/args.PNG renamed to images/docs/args.PNG

File renamed without changes.

Diff for: package.json

+35-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"debugger"
1515
],
1616
"engines": {
17-
"vscode": "^1.22.0"
17+
"vscode": "^1.32.0"
1818
},
1919
"license": "SEE LICENSE IN LICENSE.txt",
2020
"repository": {
@@ -41,7 +41,31 @@
4141
"javaExtensions": [
4242
"./server/com.microsoft.java.debug.plugin-0.18.0.jar"
4343
],
44-
"commands": [],
44+
"commands": [
45+
{
46+
"command": "java.debug.hotCodeReplace",
47+
"title": "Hot Code Replace",
48+
"icon": {
49+
"dark": "images/commands/hot_code_replace.svg",
50+
"light": "images/commands/hot_code_replace.svg"
51+
}
52+
}
53+
],
54+
"menus": {
55+
"debug/toolBar": [
56+
{
57+
"command": "java.debug.hotCodeReplace",
58+
"group": "navigation@100",
59+
"when": "inDebugMode && debugType == java && javaHotReload == 'manual'"
60+
}
61+
],
62+
"commandPalette": [
63+
{
64+
"command": "java.debug.hotCodeReplace",
65+
"when": "false"
66+
}
67+
]
68+
},
4569
"debuggers": [
4670
{
4771
"type": "java",
@@ -409,10 +433,15 @@
409433
"description": "%java.debugger.configuration.maxStringLength.description%",
410434
"default": 0
411435
},
412-
"java.debug.settings.enableHotCodeReplace": {
413-
"type": "boolean",
414-
"description": "%java.debugger.configuration.enableHotCodeReplace.description%",
415-
"default": true
436+
"java.debug.settings.hotCodeReplace": {
437+
"type": "string",
438+
"default": "manual",
439+
"description": "%java.debugger.configuration.hotCodeReplace.description%",
440+
"enum": [
441+
"auto",
442+
"manual",
443+
"never"
444+
]
416445
},
417446
"java.debug.settings.enableRunDebugCodeLens": {
418447
"type": "boolean",

Diff for: package.nls.it.json

-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,5 @@
55
"java.debugger.configuration.showStaticVariables.description": "Mostra variabili statiche nella scheda \"variabili\".",
66
"java.debugger.configuration.showQualifiedNames.description": "Mostra nome completo delle classi nella scheda \"variabili\".",
77
"java.debugger.configuration.maxStringLength.description": "Lunghezza massima delle stringhe visualizzate nella scheda \"Variabili\" o \"Console di Debug\", stringhe più lunghe di questo numero verranno tagliate, se 0 nessun taglio viene eseguito.",
8-
"java.debugger.configuration.enableHotCodeReplace.description": "Attiva sostituzione hotcode per codice Java.",
98
"java.debugger.configuration.enableRunDebugCodeLens.description": "Abilitare i provider di lenti di codice run e debug sui metodi principali."
109
}

Diff for: package.nls.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"java.debugger.configuration.showQualifiedNames.description": "Show fully qualified class names in \"Variables\" viewlet.",
4242
"java.debugger.configuration.showLogicalStructure.description": "Show the logical structure for the Collection and Map classes in \"Variables\" viewlet.",
4343
"java.debugger.configuration.maxStringLength.description": "The maximum length of strings displayed in \"Variables\" or \"Debug Console\" viewlet, strings longer than this length will be trimmed, if 0 no trim is performed.",
44-
"java.debugger.configuration.enableHotCodeReplace.description": "Enable hot code replace for Java code.",
44+
"java.debugger.configuration.hotCodeReplace.description": "Reload the changed Java classes during debugging. Make sure 'java.autobuild.enabled' is not disabled.",
4545
"java.debugger.configuration.enableRunDebugCodeLens.description": "Enable the run and debug code lens providers over main methods.",
4646
"java.debugger.configuration.forceBuildBeforeLaunch": "Force building the workspace before launching java program."
4747
}

Diff for: package.nls.zh.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"java.debugger.configuration.showQualifiedNames.description": "在“变量”视图中显示类的全名。",
4242
"java.debugger.configuration.showLogicalStructure.description": "在“变量”视图中显示Collection和Map类的逻辑结构。",
4343
"java.debugger.configuration.maxStringLength.description": "设定“变量”或“调试控制台”视图中显示的字符串最大长度,长度超过部分将被剪掉。如果值为0,则不执行修剪。",
44-
"java.debugger.configuration.enableHotCodeReplace.description": "为Java代码启用热代码替换",
44+
"java.debugger.configuration.hotCodeReplace.description": "在调试期间重新加载已更改的Java类。确保未禁用'java.autobuild.enabled'",
4545
"java.debugger.configuration.enableRunDebugCodeLens.description": "在main方法上启用CodeLens标记。",
4646
"java.debugger.configuration.forceBuildBeforeLaunch": "在启动java程序之前强制编译整个工作空间。"
4747
}

Diff for: src/extension.ts

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4-
import * as path from "path";
54
import * as vscode from "vscode";
65
import { dispose as disposeTelemetryWrapper, initializeFromJsonFile, instrumentOperation } from "vscode-extension-telemetry-wrapper";
76
import * as commands from "./commands";
@@ -49,6 +48,29 @@ function initializeExtension(operationId: string, context: vscode.ExtensionConte
4948
context.subscriptions.push(instrumentAndRegisterCommand("JavaDebug.SpecifyProgramArgs", async () => {
5049
return specifyProgramArguments(context);
5150
}));
51+
context.subscriptions.push(instrumentAndRegisterCommand("java.debug.hotCodeReplace", async (args: any) => {
52+
const autobuildConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("java.autobuild");
53+
if (!autobuildConfig.enabled) {
54+
const ans = await vscode.window.showWarningMessage(
55+
"The hot code replace feature requires you to enable the autobuild flag, do you want to enable it?",
56+
"Yes", "No");
57+
if (ans === "Yes") {
58+
await autobuildConfig.update("enabled", true);
59+
} else {
60+
return;
61+
}
62+
}
63+
64+
const debugSession: vscode.DebugSession = vscode.debug.activeDebugSession;
65+
if (!debugSession) {
66+
return;
67+
}
68+
69+
return vscode.window.withProgress({ location: vscode.ProgressLocation.Window }, async (progress) => {
70+
progress.report({ message: "Applying code changes..." });
71+
return await debugSession.customRequest("redefineClasses");
72+
});
73+
}));
5274
initializeHotCodeReplace(context);
5375
context.subscriptions.push(vscode.debug.onDidReceiveDebugSessionCustomEvent((customEvent) => {
5476
const t = customEvent.session ? customEvent.session.type : undefined;

Diff for: src/hotCodeReplace.ts

+17-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import * as vscode from "vscode";
55

66
import * as anchor from "./anchor";
7-
import { HCR_EVENT, JAVA_LANGID } from "./constants";
7+
import { JAVA_LANGID } from "./constants";
88
import * as utility from "./utility";
99

1010
const suppressedReasons: Set<string> = new Set();
@@ -24,6 +24,12 @@ enum HcrChangeType {
2424
}
2525

2626
export function initializeHotCodeReplace(context: vscode.ExtensionContext) {
27+
vscode.commands.executeCommand("setContext", "javaHotReload", getHotReloadFlag());
28+
vscode.workspace.onDidChangeConfiguration((event) => {
29+
if (event.affectsConfiguration("java.debug.settings.hotCodeReplace")) {
30+
vscode.commands.executeCommand("setContext", "javaHotReload", getHotReloadFlag());
31+
}
32+
});
2733
context.subscriptions.push(vscode.debug.onDidTerminateDebugSession((session) => {
2834
const t = session ? session.type : undefined;
2935
if (t === JAVA_LANGID) {
@@ -34,10 +40,12 @@ export function initializeHotCodeReplace(context: vscode.ExtensionContext) {
3440

3541
export function handleHotCodeReplaceCustomEvent(hcrEvent) {
3642
if (hcrEvent.body.changeType === HcrChangeType.BUILD_COMPLETE) {
37-
return vscode.window.withProgress({ location: vscode.ProgressLocation.Window }, (progress) => {
38-
progress.report({ message: "Applying code changes..." });
39-
return hcrEvent.session.customRequest("redefineClasses");
40-
});
43+
if (getHotReloadFlag() === "auto") {
44+
return vscode.window.withProgress({ location: vscode.ProgressLocation.Window }, (progress) => {
45+
progress.report({ message: "Applying code changes..." });
46+
return hcrEvent.session.customRequest("redefineClasses");
47+
});
48+
}
4149
}
4250

4351
if (hcrEvent.body.changeType === HcrChangeType.ERROR || hcrEvent.body.changeType === HcrChangeType.WARNING) {
@@ -55,3 +63,7 @@ export function handleHotCodeReplaceCustomEvent(hcrEvent) {
5563
}
5664
}
5765
}
66+
67+
function getHotReloadFlag(): string {
68+
return vscode.workspace.getConfiguration("java.debug.settings").get("hotCodeReplace") || "manual";
69+
}

0 commit comments

Comments
 (0)