Skip to content

Commit cc40399

Browse files
Skip the specified classes on exception breakpoint or stepping (#829)
* Skip the specified classes on exception breakpoint or stepping Signed-off-by: Jinbo Wang <[email protected]> * fix build error Signed-off-by: Jinbo Wang <[email protected]> * Address review comments Signed-off-by: Jinbo Wang <[email protected]>
1 parent 9931d8f commit cc40399

File tree

9 files changed

+232
-50
lines changed

9 files changed

+232
-50
lines changed

.vscode/launch.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111
"stopOnEntry": false,
1212
"sourceMaps": true,
1313
"outFiles": [ "${workspaceRoot}/out/src/**/*.js" ],
14-
"preLaunchTask": "npm: watch"
14+
"preLaunchTask": "npm: watch",
15+
"env": {
16+
"DEBUG_VSCODE_JAVA":"true"
17+
}
1518
},
1619
{
1720
"name": "Extension Tests",

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ Please also check the documentation of [Language Support for Java by Red Hat](ht
6969
- `argfile` - Generate the classpath parameters to a temporary argument file, and launch the program with the command line 'java @argfile [args]'. This value only applies to Java 9 and higher.
7070
- `auto` - Automatically detect the command line length and determine whether to shorten the command line via an appropriate approach.
7171
- `stepFilters` - Skip specified classes or methods when stepping.
72-
- `classNameFilters` - Skip the specified classes when stepping. Class names should be fully qualified. Wildcard is supported.
72+
- `classNameFilters` - [**Deprecated** - replaced by `skipClasses`] Skip the specified classes when stepping. Class names should be fully qualified. Wildcard is supported.
73+
- `skipClasses` - Skip the specified classes when stepping. You could use the built-in variables such as '$JDK' and '$Libraries' to skip a group of classes, or add a specific class name expression, e.g. java.*, *.Foo
7374
- `skipSynthetics` - Skip synthetic methods when stepping.
7475
- `skipStaticInitializers` - Skip static initializer methods when stepping.
7576
- `skipConstructors` - Skip constructor methods when stepping.
@@ -85,7 +86,8 @@ Please also check the documentation of [Language Support for Java by Red Hat](ht
8586
- `sourcePaths` - The extra source directories of the program. The debugger looks for source code from project settings by default. This option allows the debugger to look for source code in extra directories.
8687
- `projectName` - The preferred project in which the debugger searches for classes. There could be duplicated class names in different projects. It is required when the workspace has multiple java projects, otherwise the expression evaluation and conditional breakpoint may not work.
8788
- `stepFilters` - Skip specified classes or methods when stepping.
88-
- `classNameFilters` - Skip the specified classes when stepping. Class names should be fully qualified. Wildcard is supported.
89+
- `classNameFilters` - [**Deprecated** - replaced by `skipClasses`] Skip the specified classes when stepping. Class names should be fully qualified. Wildcard is supported.
90+
- `skipClasses` - Skip the specified classes when stepping. You could use the built-in variables such as '$JDK' and '$Libraries' to skip a group of classes, or add a specific class name expression, e.g. java.*, *.Foo
8991
- `skipSynthetics` - Skip synthetic methods when stepping.
9092
- `skipStaticInitializers` - Skip static initializer methods when stepping.
9193
- `skipConstructors` - Skip constructor methods when stepping.
@@ -110,6 +112,11 @@ Please also check the documentation of [Language Support for Java by Red Hat](ht
110112
- `internalConsole` - VS Code debug console (input stream not supported).
111113
- `integratedTerminal` - VS Code integrated terminal.
112114
- `externalTerminal` - External terminal that can be configured in user settings.
115+
- `java.debug.settings.exceptionBreakpoint.skipClasses`: Skip the specified classes when breaking on exception. You could use the built-in variables such as '$JDK' and '$Libraries' to skip a group of classes, or add a specific class name expression, e.g. java.*, *.Foo
116+
- `java.debug.settings.stepping.skipClasses`: Skip the specified classes when stepping. You could use the built-in variables such as '$JDK' and '$Libraries' to skip a group of classes, or add a specific class name expression, e.g. java.*, *.Foo
117+
- `java.debug.settings.stepping.skipSynthetics`: Skip synthetic methods when stepping.
118+
- `java.debug.settings.stepping.skipStaticInitializers`: Skip static initializer methods when stepping.
119+
- `java.debug.settings.stepping.skipConstructors`: Skip constructor methods when stepping.
113120

114121
Pro Tip: The documentation [Configuration.md](https://github.com/microsoft/vscode-java-debug/blob/master/Configuration.md) provides lots of samples to demonstrate how to use these debug configurations, recommend to take a look.
115122

package.json

Lines changed: 113 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -287,32 +287,40 @@
287287
"type": "object",
288288
"description": "%java.debugger.launch.stepFilters.description%",
289289
"default": {
290-
"classNameFilters": [
291-
"java.*",
292-
"javax.*",
293-
"com.sun.*",
294-
"sun.*",
295-
"sunw.*",
296-
"org.omg.*"
290+
"skipClasses": [
291+
"$JDK",
292+
"junit.*"
297293
],
298294
"skipSynthetics": false,
299295
"skipStaticInitializers": false,
300296
"skipConstructors": false
301297
},
302298
"properties": {
303-
"classNameFilters": {
299+
"skipClasses": {
304300
"type": "array",
305-
"description": "%java.debugger.launch.classNameFilters.description%",
306-
"item": {
307-
"type": "string"
301+
"description": "%java.debugger.launch.skipClasses.description%",
302+
"items": {
303+
"anyOf": [
304+
{
305+
"enum": [
306+
"$JDK",
307+
"$Libraries",
308+
"java.lang.ClassLoader",
309+
""
310+
],
311+
"enumDescriptions": [
312+
"%java.debugger.launch.skipClasses.skipJDK%",
313+
"%java.debugger.launch.skipClasses.skipLibraries%",
314+
"%java.debugger.launch.skipClasses.skipClassLoader%",
315+
"%java.debugger.launch.skipClasses.skipClassPattern%"
316+
]
317+
},
318+
"string"
319+
]
308320
},
309321
"default": [
310-
"java.*",
311-
"javax.*",
312-
"com.sun.*",
313-
"sun.*",
314-
"sunw.*",
315-
"org.omg.*"
322+
"$JDK",
323+
"junit.*"
316324
]
317325
},
318326
"skipSynthetics": {
@@ -382,32 +390,40 @@
382390
"type": "object",
383391
"description": "%java.debugger.launch.stepFilters.description%",
384392
"default": {
385-
"classNameFilters": [
386-
"java.*",
387-
"javax.*",
388-
"com.sun.*",
389-
"sun.*",
390-
"sunw.*",
391-
"org.omg.*"
393+
"skipClasses": [
394+
"$JDK",
395+
"junit.*"
392396
],
393397
"skipSynthetics": false,
394398
"skipStaticInitializers": false,
395399
"skipConstructors": false
396400
},
397401
"properties": {
398-
"classNameFilters": {
402+
"skipClasses": {
399403
"type": "array",
400-
"description": "%java.debugger.launch.classNameFilters.description%",
401-
"item": {
402-
"type": "string"
404+
"description": "%java.debugger.launch.skipClasses.description%",
405+
"items": {
406+
"anyOf": [
407+
{
408+
"enum": [
409+
"$JDK",
410+
"$Libraries",
411+
"java.lang.ClassLoader",
412+
""
413+
],
414+
"enumDescriptions": [
415+
"%java.debugger.launch.skipClasses.skipJDK%",
416+
"%java.debugger.launch.skipClasses.skipLibraries%",
417+
"%java.debugger.launch.skipClasses.skipClassLoader%",
418+
"%java.debugger.launch.skipClasses.skipClassPattern%"
419+
]
420+
},
421+
"string"
422+
]
403423
},
404424
"default": [
405-
"java.*",
406-
"javax.*",
407-
"com.sun.*",
408-
"sun.*",
409-
"sunw.*",
410-
"org.omg.*"
425+
"$JDK",
426+
"junit.*"
411427
]
412428
},
413429
"skipSynthetics": {
@@ -592,6 +608,69 @@
592608
],
593609
"description": "%java.debugger.configuration.console%",
594610
"default": "integratedTerminal"
611+
},
612+
"java.debug.settings.exceptionBreakpoint.skipClasses": {
613+
"type": "array",
614+
"description": "%java.debugger.configuration.exceptionBreakpoint.skipClasses%",
615+
"items": {
616+
"anyOf": [
617+
{
618+
"enum": [
619+
"$JDK",
620+
"$Libraries",
621+
"java.lang.ClassLoader",
622+
""
623+
],
624+
"enumDescriptions": [
625+
"%java.debugger.launch.skipClasses.skipJDK%",
626+
"%java.debugger.launch.skipClasses.skipLibraries%",
627+
"%java.debugger.launch.skipClasses.skipClassLoader%",
628+
"%java.debugger.launch.skipClasses.skipClassPattern%"
629+
]
630+
},
631+
"string"
632+
]
633+
},
634+
"default": []
635+
},
636+
"java.debug.settings.stepping.skipClasses": {
637+
"type": "array",
638+
"description": "%java.debugger.launch.skipClasses.description%",
639+
"items": {
640+
"anyOf": [
641+
{
642+
"enum": [
643+
"$JDK",
644+
"$Libraries",
645+
"java.lang.ClassLoader",
646+
""
647+
],
648+
"enumDescriptions": [
649+
"%java.debugger.launch.skipClasses.skipJDK%",
650+
"%java.debugger.launch.skipClasses.skipLibraries%",
651+
"%java.debugger.launch.skipClasses.skipClassLoader%",
652+
"%java.debugger.launch.skipClasses.skipClassPattern%"
653+
]
654+
},
655+
"string"
656+
]
657+
},
658+
"default": []
659+
},
660+
"java.debug.settings.stepping.skipSynthetics": {
661+
"type": "boolean",
662+
"description": "%java.debugger.launch.skipSynthetics.description%",
663+
"default": false
664+
},
665+
"java.debug.settings.stepping.skipStaticInitializers": {
666+
"type": "boolean",
667+
"description": "%java.debugger.launch.skipStaticInitializers.description%",
668+
"default": false
669+
},
670+
"java.debug.settings.stepping.skipConstructors": {
671+
"type": "boolean",
672+
"description": "%java.debugger.launch.skipConstructors.description%",
673+
"default": false
595674
}
596675
}
597676
}

package.nls.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
"java.debugger.launch.shortenCommandLine.argfile": "Generate the classpath parameters to a temporary argument file, and launch the program with the command line 'java @argfile [args]'. This value only applies to Java 9 and higher.",
2121
"java.debugger.launch.shortenCommandLine.description": "When the project has long classpath or big VM arguments, the command line to launch the program may exceed the maximum command line string limitation allowed by the OS. This configuration item provides multiple approaches to shorten the command line.",
2222
"java.debugger.launch.stepFilters.description": "Skip specified classes or methods when stepping.",
23-
"java.debugger.launch.classNameFilters.description": "Skip the specified classes when stepping. Class names should be fully qualified. Wildcard is supported.",
23+
"java.debugger.launch.skipClasses.description": "Skip the specified classes when stepping. You could use the built-in variables such as '$JDK' and '$Libraries' to skip a group of classes, or add a specific class name expression, e.g. java.*, *.Foo",
24+
"java.debugger.launch.skipClasses.skipJDK": "Skip the JDK classes from the default system bootstrap classpath, such as rt.jar, jrt-fs.jar.",
25+
"java.debugger.launch.skipClasses.skipLibraries": "Skip the classes from application libraries, such as Maven, Gradle dependencies.",
26+
"java.debugger.launch.skipClasses.skipClassLoader": "Skip the class loaders.",
27+
"java.debugger.launch.skipClasses.skipClassPattern": "Skip the specified classes. Class names should be fully qualified. Wildcard is supported, e.g. java.*, *.Foo",
2428
"java.debugger.launch.skipSynthetics.description": "Skip synthetic methods when stepping.",
2529
"java.debugger.launch.skipStaticInitializers.description": "Skip static initializer methods when stepping.",
2630
"java.debugger.launch.skipConstructors.description": "Skip constructor methods when stepping.",
@@ -49,5 +53,6 @@
4953
"java.debugger.configuration.hotCodeReplace.description": "Reload the changed Java classes during debugging. Make sure 'java.autobuild.enabled' is not disabled.",
5054
"java.debugger.configuration.enableRunDebugCodeLens.description": "Enable the run and debug code lens providers over main methods.",
5155
"java.debugger.configuration.forceBuildBeforeLaunch": "Force building the workspace before launching java program.",
52-
"java.debugger.configuration.console": "The specified console to launch Java program. If you want to customize the console for a specific debug session, please modify the 'console' config in launch.json."
56+
"java.debugger.configuration.console": "The specified console to launch Java program. If you want to customize the console for a specific debug session, please modify the 'console' config in launch.json.",
57+
"java.debugger.configuration.exceptionBreakpoint.skipClasses": "Skip the specified classes when breaking on exception. You could use the built-in variables such as '$JDK' and '$Libraries' to skip a group of classes, or add a specific class name expression, e.g. java.*, *.Foo"
5358
}

package.nls.zh.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
"java.debugger.launch.shortenCommandLine.argfile": "将类路径参数生成到临时 argument 文件中, 并使用命令行 'java @argfile [args]' 启动应用程序。该值仅适用于 Java 9 及以上版本。",
2121
"java.debugger.launch.shortenCommandLine.description": "当项目具有较长的类路径或较大的VM参数时,启动程序的命令行可能会超出OS允许的最大命令行字符串限制。此配置项提供了多种缩短命令行的方法。",
2222
"java.debugger.launch.stepFilters.description": "Step时跳过指定的类或方法。",
23-
"java.debugger.launch.classNameFilters.description": "Step时跳过指定的类。仅支持全名,以及通配符。",
23+
"java.debugger.launch.skipClasses.description": "Step时跳过指定的类。你可以使用内置变量,如'$JDK'和'$Libraries'来跳过一组类,或者添加一个特定的类名表达式,如java.*,*.Foo。",
24+
"java.debugger.launch.skipClasses.skipJDK": "跳过系统默认的启动路径中的JDK类,如rt.jar、jrt-fs.jar。",
25+
"java.debugger.launch.skipClasses.skipLibraries": "跳过应用库中的类,如Maven、Gradle依赖。",
26+
"java.debugger.launch.skipClasses.skipClassLoader": "跳过类加载器。",
27+
"java.debugger.launch.skipClasses.skipClassPattern": "跳过指定的类。仅支持全名,以及通配符,如java.*,*.Foo。",
2428
"java.debugger.launch.skipSynthetics.description": "Step时跳过合成方法。",
2529
"java.debugger.launch.skipStaticInitializers.description": "Step时跳过静态初始化方法。",
2630
"java.debugger.launch.skipConstructors.description": "Step时跳过构造函数。",
@@ -48,5 +52,6 @@
4852
"java.debugger.configuration.hotCodeReplace.description": "在调试期间重新加载已更改的Java类。确保未禁用'java.autobuild.enabled'。",
4953
"java.debugger.configuration.enableRunDebugCodeLens.description": "在main方法上启用CodeLens标记。",
5054
"java.debugger.configuration.forceBuildBeforeLaunch": "在启动java程序之前强制编译整个工作空间。",
51-
"java.debugger.configuration.console": "指定的控制台用于启动Java程序。如果要为特定的调试会话自定义控制台,请修改launch.json中的“console”配置。"
55+
"java.debugger.configuration.console": "指定的控制台用于启动Java程序。如果要为特定的调试会话自定义控制台,请修改launch.json中的“console”配置。",
56+
"java.debugger.configuration.exceptionBreakpoint.skipClasses": "当发生异常时,跳过指定的类。你可以使用内置变量,如'$JDK'和'$Libraries'来跳过一组类,或者添加一个特定的类名表达式,如java.*,*.Foo。"
5257
}

src/classFilter.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
import * as vscode from "vscode";
5+
import { resolveClassFilters } from "./languageServerPlugin";
6+
7+
export async function populateStepFilters(config: vscode.DebugConfiguration) {
8+
if (!config.stepFilters) {
9+
return;
10+
}
11+
12+
const skipClasses = await substituteFilterVariables(config.stepFilters.skipClasses);
13+
// Migrate classNameFilters to skipClasses.
14+
if (Array.isArray(config.stepFilters.classNameFilters)) {
15+
mergeResult(config.stepFilters.classNameFilters, skipClasses);
16+
}
17+
config.stepFilters.classNameFilters = undefined;
18+
config.stepFilters.skipClasses = skipClasses;
19+
}
20+
21+
export async function substituteFilterVariables(skipClasses: string[]): Promise<any> {
22+
if (!skipClasses) {
23+
return [];
24+
}
25+
26+
try {
27+
// Preprocess skipClasses configurations.
28+
if (Array.isArray(skipClasses)) {
29+
const hasReservedName = skipClasses.some((filter) => filter === "$JDK" || filter === "$Libraries");
30+
return hasReservedName ? await resolveClassFilters(skipClasses) : skipClasses;
31+
} else {
32+
// tslint:disable-next-line:no-console
33+
console.error("Invalid type for skipClasses config:" + skipClasses);
34+
}
35+
} catch (e) {
36+
// tslint:disable-next-line:no-console
37+
console.error(e);
38+
}
39+
40+
return [];
41+
}
42+
43+
function mergeResult(newItems: any[], result: string[]) {
44+
newItems.forEach((item) => {
45+
if (result.indexOf(item) < 0) {
46+
result.push(String(item));
47+
}
48+
});
49+
}

src/commands.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ export const JAVA_RESOLVE_JAVAEXECUTABLE = "vscode.java.resolveJavaExecutable";
4040

4141
export const JAVA_FETCH_PLATFORM_SETTINGS = "vscode.java.fetchPlatformSettings";
4242

43+
export const JAVA_RESOLVE_CLASSFILTERS = "vscode.java.resolveClassFilters";
44+
4345
export function executeJavaLanguageServerCommand(...rest) {
4446
return executeJavaExtensionCommand(JAVA_EXECUTE_WORKSPACE_COMMAND, ...rest);
4547
}

0 commit comments

Comments
 (0)