-
Notifications
You must be signed in to change notification settings - Fork 410
Provide jarmanifest/argfile approachs to shorten the command line #532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
9f67134
Provide jarmainifest/argfile approachs to shorten the command line
testforstephen 5f11372
Add new launch.json config to README
testforstephen 00d17ae
Fix the localizable words per comments
testforstephen 56c89e3
Merge branch 'master' into jinbo_cli
testforstephen 75eb170
Add auto mode to auto detect the right approach to shorten command line
testforstephen 24bc2cd
fix build error
testforstephen 1569569
Address the review comments
testforstephen 5d32da1
Differentiate the command line length limit for different OS
testforstephen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT license. | ||
| import * as cp from "child_process"; | ||
| import * as _ from "lodash"; | ||
| import * as path from "path"; | ||
| import * as vscode from "vscode"; | ||
|
|
||
| import { inferLaunchCommandLength } from "./languageServerPlugin"; | ||
| import { getJavaHome } from "./utility"; | ||
|
|
||
| enum shortenApproach { | ||
| none = "none", | ||
| jarmanifest = "jarmanifest", | ||
| argfile = "argfile", | ||
| } | ||
|
|
||
| export async function detectLaunchCommandStyle(config: vscode.DebugConfiguration): Promise<shortenApproach> { | ||
| const javaHome = await getJavaHome(); | ||
| const javaVersion = await checkJavaVersion(javaHome); | ||
| const recommendedShortenApproach = javaVersion <= 8 ? shortenApproach.jarmanifest : shortenApproach.argfile; | ||
| return (await shouldShortenIfNecessary(config)) ? recommendedShortenApproach : shortenApproach.none; | ||
| } | ||
|
|
||
| function checkJavaVersion(javaHome: string): Promise<number> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agree. but prefer to do it with a new PR when the change in vscode-java is ready. |
||
| return new Promise((resolve, reject) => { | ||
| cp.execFile(javaHome + "/bin/java", ["-version"], {}, (error, stdout, stderr) => { | ||
| const javaVersion = parseMajorVersion(stderr); | ||
| resolve(javaVersion); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| function parseMajorVersion(content: string): number { | ||
| let regexp = /version "(.*)"/g; | ||
| let match = regexp.exec(content); | ||
| if (!match) { | ||
| return 0; | ||
| } | ||
| let version = match[1]; | ||
| // Ignore '1.' prefix for legacy Java versions | ||
| if (version.startsWith("1.")) { | ||
| version = version.substring(2); | ||
| } | ||
|
|
||
| // look into the interesting bits now | ||
| regexp = /\d+/g; | ||
| match = regexp.exec(version); | ||
| let javaVersion = 0; | ||
| if (match) { | ||
| javaVersion = parseInt(match[0], 10); | ||
| } | ||
| return javaVersion; | ||
| } | ||
|
|
||
| async function shouldShortenIfNecessary(config: vscode.DebugConfiguration): Promise<boolean> { | ||
| const cliLength = await inferLaunchCommandLength(config); | ||
| const classPathLength = (config.classPaths || []).join(path.delimiter).length; | ||
| const modulePathLength = (config.modulePaths || []).join(path.delimiter).length; | ||
| if (!config.console || config.console === "internalConsole") { | ||
| return cliLength >= getMaxProcessCommandLineLength(config) || classPathLength >= getMaxArgLength() || modulePathLength >= getMaxArgLength(); | ||
| } else { | ||
| return cliLength >= getMaxTerminalCommandLineLength(config) || classPathLength >= getMaxArgLength() || modulePathLength >= getMaxArgLength(); | ||
| } | ||
| } | ||
|
|
||
| function getMaxProcessCommandLineLength(config: vscode.DebugConfiguration): number { | ||
| const ARG_MAX_WINDOWS = 32768; | ||
| const ARG_MAX_MACOS = 262144; | ||
| const ARG_MAX_LINUX = 2097152; | ||
| // for Posix systems, ARG_MAX is the maximum length of argument to the exec functions including environment data. | ||
| // POSIX suggests to subtract 2048 additionally so that the process may safely modify its environment. | ||
| // see https://www.in-ulm.de/~mascheck/various/argmax/ | ||
| if (process.platform === "win32") { | ||
| // https://blogs.msdn.microsoft.com/oldnewthing/20031210-00/?p=41553/ | ||
| // On windows, the max process commmand line length is 32k (32768) characters. | ||
| return ARG_MAX_WINDOWS - 2048; | ||
| } else if (process.platform === "darwin") { | ||
| return ARG_MAX_MACOS - getEnvironmentLength(config) - 2048; | ||
| } else if (process.platform === "linux") { | ||
| return ARG_MAX_LINUX - getEnvironmentLength(config) - 2048; | ||
| } | ||
|
|
||
| return Number.MAX_SAFE_INTEGER; | ||
| } | ||
|
|
||
| function getMaxTerminalCommandLineLength(config: vscode.DebugConfiguration): number { | ||
| const MAX_CMD_WINDOWS = 8192; | ||
| if (process.platform === "win32") { | ||
| // https://support.microsoft.com/en-us/help/830473/command-prompt-cmd--exe-command-line-string-limitation | ||
| // On windows, the max command line length for cmd terminal is 8192 characters. | ||
| return MAX_CMD_WINDOWS; | ||
| } | ||
|
|
||
| return getMaxProcessCommandLineLength(config); | ||
| } | ||
|
|
||
| function getEnvironmentLength(config: vscode.DebugConfiguration): number { | ||
| const env = config.env || {}; | ||
| return _.isEmpty(env) ? 0 : Object.keys(env).map((key) => strlen(key) + strlen(env[key]) + 1).reduce((a, b) => a + b); | ||
| } | ||
|
|
||
| function strlen(str: string): number { | ||
| return str ? str.length : 0; | ||
| } | ||
|
|
||
| function getMaxArgLength(): number { | ||
| const MAX_ARG_STRLEN_LINUX = 131072; | ||
| if (process.platform === "linux") { | ||
| // On Linux, MAX_ARG_STRLEN (kernel >= 2.6.23) is the maximum length of a command line argument (or environment variable). Its value | ||
| // cannot be changed without recompiling the kernel. | ||
| return MAX_ARG_STRLEN_LINUX - 2048; | ||
| } | ||
|
|
||
| return Number.MAX_SAFE_INTEGER; | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add 'auto' as the default value to unblock majority of use cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A new PR microsoft/java-debug#254 on java-debug to help compute the launch command length.