Connect to Spring process directly, no tracking
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017, 2019 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2022 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -30,7 +30,7 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public class BootJavaConfig implements InitializingBean {
|
||||
|
||||
public static final boolean LIVE_INFORMATION_AUTOMATIC_TRACKING_ENABLED_DEFAULT = true;
|
||||
public static final boolean LIVE_INFORMATION_AUTOMATIC_TRACKING_ENABLED_DEFAULT = false;
|
||||
public static final int LIVE_INFORMATION_AUTOMATIC_TRACKING_DELAY_DEFAULT = 5000;
|
||||
|
||||
public static final int LIVE_INFORMATION_FETCH_DATA_RETRY_MAX_NO_DEFAULT = 10;
|
||||
|
||||
@@ -17,7 +17,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -93,6 +92,8 @@ public class SpringProcessCommandHandler {
|
||||
|
||||
// try local processes
|
||||
if (SpringProcessConnectorLocal.isAvailable()) {
|
||||
|
||||
// Try cached processes.
|
||||
SpringProcessDescriptor[] processes = localProcessConnector.getProcesses(false, SpringProcessStatus.REGULAR, SpringProcessStatus.AUTO_CONNECT);
|
||||
for (SpringProcessDescriptor process : processes) {
|
||||
if (process.getProcessKey().equals(processKey)) {
|
||||
@@ -100,6 +101,15 @@ public class SpringProcessCommandHandler {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
|
||||
processes = localProcessConnector.getProcesses(true, SpringProcessStatus.REGULAR, SpringProcessStatus.AUTO_CONNECT);
|
||||
for (SpringProcessDescriptor process : processes) {
|
||||
if (process.getProcessKey().equals(processKey)) {
|
||||
localProcessConnector.connectProcess(process);
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// try remote processes
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019, 2020 Pivotal, Inc.
|
||||
* Copyright (c) 2019, 2022 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -142,7 +142,7 @@ public class SpringProcessConnectorService {
|
||||
* common method to generate process keys from process IDs and process names
|
||||
*/
|
||||
public static String getProcessKey(String processID, String processName) {
|
||||
return processID + " - " + processName;
|
||||
return processID;
|
||||
}
|
||||
|
||||
private void scheduleConnect(ProgressTask progressTask, String processKey, SpringProcessConnector connector, long delay, TimeUnit unit, int retryNo) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { CancellationToken, DebugConfiguration, DebugConfigurationProvider, Prov
|
||||
import * as path from "path";
|
||||
import * as VSCode from "vscode";
|
||||
import { Disposable } from "vscode";
|
||||
import psList from 'ps-list';
|
||||
|
||||
const JMX_VM_ARG = '-Dspring.jmx.enabled='
|
||||
const ADMIN_VM_ARG = '-Dspring.application.admin.enabled='
|
||||
@@ -10,7 +11,7 @@ const BOOT_PROJECT_ARG = '-Dspring.boot.project.name=';
|
||||
class SpringBootDebugConfigProvider implements DebugConfigurationProvider {
|
||||
|
||||
resolveDebugConfigurationWithSubstitutedVariables(folder: WorkspaceFolder | undefined, debugConfiguration: DebugConfiguration, token?: CancellationToken): ProviderResult<DebugConfiguration> {
|
||||
if (isAutoConnect() && this.isActuatorOnClasspath(debugConfiguration)) {
|
||||
if (isAutoConnect() && isActuatorOnClasspath(debugConfiguration)) {
|
||||
if (debugConfiguration.vmArgs) {
|
||||
if (debugConfiguration.vmArgs.indexOf(JMX_VM_ARG) < 0) {
|
||||
debugConfiguration.vmArgs += ` ${JMX_VM_ARG}true`;
|
||||
@@ -28,28 +29,69 @@ class SpringBootDebugConfigProvider implements DebugConfigurationProvider {
|
||||
return debugConfiguration;
|
||||
}
|
||||
|
||||
private isActuatorOnClasspath(debugConfiguration: DebugConfiguration): boolean {
|
||||
if (Array.isArray(debugConfiguration.classPaths)) {
|
||||
return !!debugConfiguration.classPaths.find(this.isActuatorJarFile);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private isActuatorJarFile(f: string): boolean {
|
||||
const fileName = path.basename(f || "");
|
||||
if (/^spring-boot-actuator-\d+\.\d+\.\d+(.*)?.jar$/.test(fileName)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
interface ProcessEvent {
|
||||
type: string;
|
||||
pid: number;
|
||||
shellProcessId: number
|
||||
}
|
||||
|
||||
export function startDebugSupport(): Disposable {
|
||||
// VSCode.debug.onDidStartDebugSession(handleDebugSessionStarted);
|
||||
VSCode.debug.onDidReceiveDebugSessionCustomEvent(handleCustomDebugEvent);
|
||||
return VSCode.debug.registerDebugConfigurationProvider('java', new SpringBootDebugConfigProvider(), VSCode.DebugConfigurationProviderTriggerKind.Initial);
|
||||
}
|
||||
|
||||
function isAutoConnect(): boolean {
|
||||
return VSCode.workspace.getConfiguration("boot-java.live-information.automatic-tracking")?.get('on');
|
||||
async function handleCustomDebugEvent(e: VSCode.DebugSessionCustomEvent): Promise<void> {
|
||||
if (e.session?.type === 'java' && e?.body?.type === 'processid') {
|
||||
const debugConfiguration: DebugConfiguration = e.session.configuration;
|
||||
if (isBootAppWithJmxSetup(debugConfiguration)) {
|
||||
setTimeout(async () => {
|
||||
const pid = await getAppPid(e.body as ProcessEvent);
|
||||
const processKey = pid.toString();
|
||||
VSCode.commands.executeCommand('sts/livedata/connect', { processKey });
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function getAppPid(e: ProcessEvent): Promise<number> {
|
||||
if (e.pid) {
|
||||
return e.pid;
|
||||
} else if (e.shellProcessId) {
|
||||
const processes = await psList();
|
||||
const appProcess = processes.find(p => p.ppid === e.shellProcessId);
|
||||
if (appProcess) {
|
||||
return appProcess.pid;
|
||||
}
|
||||
throw Error(`No child process found for parent shell process with pid = ${e.shellProcessId}`);
|
||||
} else {
|
||||
throw Error('No pid or parent shell process id available');
|
||||
}
|
||||
}
|
||||
|
||||
function isActuatorOnClasspath(debugConfiguration: DebugConfiguration): boolean {
|
||||
if (Array.isArray(debugConfiguration.classPaths)) {
|
||||
return !!debugConfiguration.classPaths.find(isActuatorJarFile);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isActuatorJarFile(f: string): boolean {
|
||||
const fileName = path.basename(f || "");
|
||||
if (/^spring-boot-actuator-\d+\.\d+\.\d+(.*)?.jar$/.test(fileName)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isBootAppWithJmxSetup(debugConfiguration: DebugConfiguration): boolean {
|
||||
return debugConfiguration.vmArgs.indexOf(`${JMX_VM_ARG}true`) >= 0
|
||||
&& debugConfiguration.vmArgs.indexOf(`${ADMIN_VM_ARG}true`) >= 0
|
||||
&& debugConfiguration.vmArgs.indexOf(`${BOOT_PROJECT_ARG}${debugConfiguration.projectName}`) >= 0
|
||||
&& isActuatorOnClasspath(debugConfiguration);
|
||||
}
|
||||
|
||||
function isAutoConnect(): boolean {
|
||||
return VSCode.workspace.getConfiguration("boot-java.live-information.automatic-connection")?.get('on');
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ import { ActivatorOptions } from '@pivotal-tools/commons-vscode';
|
||||
interface ProcessCommandInfo {
|
||||
processKey : string;
|
||||
label: string;
|
||||
action: string
|
||||
action: string;
|
||||
projectName: string;
|
||||
}
|
||||
|
||||
async function liveHoverConnectHandler() {
|
||||
|
||||
@@ -75,15 +75,10 @@
|
||||
"type": "object",
|
||||
"title": "Boot-Java Configuration",
|
||||
"properties": {
|
||||
"boot-java.live-information.automatic-tracking.on": {
|
||||
"boot-java.live-information.automatic-connection.on": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Live Information - Automatic Process Tracking Enabled"
|
||||
},
|
||||
"boot-java.live-information.automatic-tracking.delay": {
|
||||
"type": "number",
|
||||
"default": 5000,
|
||||
"description": "Live Information - Automatic Process Tracking Delay in ms"
|
||||
"description": "Live Information - Automatic Process Connection Enabled"
|
||||
},
|
||||
"boot-java.live-information.fetch-data.max-retries": {
|
||||
"type": "number",
|
||||
@@ -518,13 +513,14 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@pivotal-tools/commons-vscode": "file:../commons-vscode/pivotal-tools-commons-vscode-0.2.4.tgz",
|
||||
"ps-list": "^7.2.0",
|
||||
"vscode-languageclient": "^7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.11",
|
||||
"@types/vscode": "^1.53.0",
|
||||
"typescript": "^4.1.2",
|
||||
"vsce": "^2.5.1"
|
||||
"vsce": "^2.6.7"
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"redhat.java"
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
"declaration": true,
|
||||
"outDir": "out",
|
||||
"sourceMap": true,
|
||||
"rootDir": "."
|
||||
"rootDir": ".",
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"include": [
|
||||
"typings/*.d.ts",
|
||||
|
||||
Reference in New Issue
Block a user