-
Notifications
You must be signed in to change notification settings - Fork 99
Expand file tree
/
Copy pathjavaServerStarter.ts
More file actions
137 lines (126 loc) · 4.95 KB
/
javaServerStarter.ts
File metadata and controls
137 lines (126 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import * as os from 'os';
import * as path from 'path';
import { ExtensionContext, window, workspace } from 'vscode';
import { Executable } from 'vscode-languageclient/node';
import { getProxySettings, getProxySettingsAsJVMArgs, jvmArgsContainsProxySettings, ProxySettings } from '../../settings/proxySettings';
import { getJavaagentFlag, getKey, getXMLConfiguration, IS_WORKSPACE_VMARGS_XML_ALLOWED, xmlServerVmargs } from '../../settings/settings';
import { RequirementsData } from '../requirements';
import { HEAP_DUMP_LOCATION, CRASH_ON_OOM, HEAP_DUMP } from './jvmArguments';
import * as glob from 'glob';
// eslint-disable-next-line no-var
declare var v8debug;
export const DEBUG = (typeof v8debug === 'object') || startedInDebugMode();
export async function prepareJavaExecutable(
context: ExtensionContext,
requirements: RequirementsData,
xmlJavaExtensions: string[]
): Promise<Executable> {
return {
command: path.resolve(requirements.java_home + '/bin/java'),
args: prepareParams(requirements, xmlJavaExtensions, context)
} as Executable;
}
function prepareParams(requirements: RequirementsData, xmlJavaExtensions: string[], context: ExtensionContext): string[] {
const params: string[] = [];
if (DEBUG) {
if (process.env['SUSPEND_SERVER'] === 'true') {
params.push('-agentlib:jdwp=transport=dt_socket,server=y,address=1054');
} else {
params.push('-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1054,quiet=y');
}
}
let vmargsCheck = workspace.getConfiguration().inspect(xmlServerVmargs).workspaceValue;
if (vmargsCheck !== undefined) {
const agentFlag = getJavaagentFlag(vmargsCheck);
if (agentFlag !== null) {
const keyVmargs = getKey(IS_WORKSPACE_VMARGS_XML_ALLOWED, context.storagePath, vmargsCheck);
const key = context.globalState.get(keyVmargs);
if (key !== true) {
vmargsCheck = workspace.getConfiguration().inspect(xmlServerVmargs).globalValue;
}
}
} else {
vmargsCheck = getXMLConfiguration().get('server.vmargs');
}
let vmargs: string;
if (vmargsCheck !== undefined) {
vmargs = vmargsCheck + '';
} else {
vmargs = '';
}
const proxySettings: ProxySettings = getProxySettings();
if (proxySettings && !jvmArgsContainsProxySettings(vmargs)) {
vmargs += getProxySettingsAsJVMArgs(proxySettings);
}
if (os.platform() == 'win32') {
const watchParentProcess = '-DwatchParentProcess=';
if (vmargs.indexOf(watchParentProcess) < 0) {
params.push(watchParentProcess + 'false');
}
}
if (vmargs.indexOf(CRASH_ON_OOM) < 0) {
params.push(CRASH_ON_OOM);
}
if (vmargs.indexOf(HEAP_DUMP) < 0) {
params.push(HEAP_DUMP);
}
if (vmargs.indexOf(HEAP_DUMP_LOCATION) < 0) {
params.push(`${HEAP_DUMP_LOCATION}${context.globalStorageUri.fsPath}`);
} else {
window.showWarningMessage('Heap dump location has been modified. '
+ 'vscode-xml won\'t delete the heap dumps. '
+ 'vscode-xml\'s Out Of Memory detection won\'t work properly, '
+ 'unless you manually delete the heap dumps after each Out Of Memory crash.');
}
// "OpenJDK 64-Bit Server VM warning: Options -Xverify:none and -noverify
// were deprecated in JDK 13 and will likely be removed in a future release."
// so only add -noverify for older versions
if (params.indexOf('-noverify') < 0 && params.indexOf('-Xverify:none') < 0 && requirements.java_version < 13) {
params.push('-noverify');
}
parseVMargs(params, vmargs);
const server_home: string = path.resolve(__dirname, '../server');
const launchersFound: Array<string> = glob.sync('**/org.eclipse.lemminx*-uber.jar', { cwd: server_home });
if (launchersFound.length) {
let xmlJavaExtensionsClasspath = '';
if (xmlJavaExtensions.length > 0) {
const pathSeparator = os.platform() == 'win32' ? ';' : ':';
xmlJavaExtensionsClasspath = pathSeparator + xmlJavaExtensions.join(pathSeparator);
}
params.push('-cp'); params.push(path.resolve(server_home, launchersFound[0]) + xmlJavaExtensionsClasspath);
params.push('org.eclipse.lemminx.XMLServerLauncher');
} else {
return null;
}
return params;
}
function startedInDebugMode(): boolean {
const args = (process as any).execArgv as string[];
return hasDebugFlag(args);
}
function hasDebugFlag(args: string[]): boolean {
if (args) {
// See https://nodejs.org/en/docs/guides/debugging-getting-started/
return args.some(arg => /^--inspect/.test(arg) || /^--debug/.test(arg));
}
return false;
}
//exported for tests
export function parseVMargs(params: any[], vmargsLine: string) {
if (!vmargsLine) {
return;
}
const vmargs = vmargsLine.match(/(?:[^\s"]+|"[^"]*")+/g);
if (vmargs === null) {
return;
}
vmargs.forEach(arg => {
//remove all standalone double quotes
arg = arg.replace(/(\\)?"/g, function ($0, $1) { return ($1 ? $0 : ''); });
//unescape all escaped double quotes
arg = arg.replace(/(\\)"/g, '"');
if (params.indexOf(arg) < 0) {
params.push(arg);
}
});
}