diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/plugin.xml b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/plugin.xml index 5dbdab06c..920c98636 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/plugin.xml +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/plugin.xml @@ -327,11 +327,5 @@ class="org.springframework.ide.eclipse.boot.dash.remoteapps.RemoteAppsFromBootDash"> - - - - diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/BootDashActivator.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/BootDashActivator.java index 863bf3335..d44eea739 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/BootDashActivator.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/BootDashActivator.java @@ -11,6 +11,7 @@ package org.springframework.ide.eclipse.boot.dash; import java.time.Duration; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -21,13 +22,14 @@ import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.model.IProcess; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; +import org.springframework.ide.eclipse.boot.core.BootPropertyTester; import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; import org.springframework.ide.eclipse.boot.dash.liveprocess.CommandInfo; import org.springframework.ide.eclipse.boot.dash.liveprocess.LiveProcessCommandsExecutor; @@ -104,7 +106,7 @@ public class BootDashActivator extends AbstractUIPlugin { super.start(context); plugin = this; new M2ELogbackCustomizer().schedule(); - connectToLaunchedBootApps(); + listenToLaunchedBootApps(); } /* @@ -114,6 +116,7 @@ public class BootDashActivator extends AbstractUIPlugin { * BundleContext) */ public void stop(BundleContext context) throws Exception { + stopListeningToLaunchedBootApps(); plugin = null; super.stop(context); if (model!=null) { @@ -195,60 +198,56 @@ public class BootDashActivator extends AbstractUIPlugin { @Override public void stateChanged(ILaunchConfiguration owner) { - if (BootLaunchConfigurationDelegate.getEnableJmx(owner)) { - LocalBootDashModel localModel = (LocalBootDashModel) getModel().getSectionByTargetId(RunTargets.LOCAL.getId()); - LaunchConfRunStateTracker tracker = localModel.getLaunchConfRunStateTracker(); - RunState state = tracker.getState(owner); - if (state == RunState.RUNNING || state == RunState.DEBUGGING) { - for (ILaunch l : DebugPlugin.getDefault().getLaunchManager().getLaunches()) { - if (l.getLaunchConfiguration() == owner) { - for (IProcess p : l.getProcesses()) { - String pid = p.getAttribute(IProcess.ATTR_PROCESS_ID); - if (pid != null) { - List servers = LiveProcessCommandsExecutor.getDefault() - .getLanguageServers(); + if (BootLaunchConfigurationDelegate.getEnableJmx(owner) && BootLaunchConfigurationDelegate.getAutoConnect(owner)) { + IJavaProject project = JavaCore.create(BootLaunchConfigurationDelegate.getProject(owner)); + try { + if (project != null && Arrays.stream(project.getResolvedClasspath(true)).anyMatch(BootPropertyTester::isActuatorJar)) { + LocalBootDashModel localModel = (LocalBootDashModel) getModel().getSectionByTargetId(RunTargets.LOCAL.getId()); + LaunchConfRunStateTracker tracker = localModel.getLaunchConfRunStateTracker(); + RunState state = tracker.getState(owner); + if (state == RunState.RUNNING || state == RunState.DEBUGGING) { + for (ILaunch l : DebugPlugin.getDefault().getLaunchManager().getLaunches()) { + if (l.getLaunchConfiguration() == owner) { + for (IProcess p : l.getProcesses()) { + String pid = p.getAttribute(IProcess.ATTR_PROCESS_ID); + if (pid != null) { + List servers = LiveProcessCommandsExecutor.getDefault() + .getLanguageServers(); - CommandInfo cmd = new CommandInfo("sts/livedata/connect", - Map.of("processKey", pid)); + CommandInfo cmd = new CommandInfo("sts/livedata/connect", + Map.of("processKey", pid)); - // The delay seems to be necessary for the moment. Although the process is created VM attach API may not work at early stages of the process run. - // "VirtualMachine.list()" call may not list the newly created process which means the process is gone and triggers disconnect. - // If lifecycle management is enabled the ready state seem to be a great indicator of a boot process fully started. - // TODO: explore health endpoint perhaps instead of ready state under Admin endpoint. - Flux.fromIterable(servers).flatMap(s -> Mono.delay(Duration.ofMillis(500)).then(s.executeCommand(cmd))).subscribe(); + // The delay seems to be necessary for the moment. Although the process is created VM attach API may not work at early stages of the process run. + // "VirtualMachine.list()" call may not list the newly created process which means the process is gone and triggers disconnect. + // If lifecycle management is enabled the ready state seem to be a great indicator of a boot process fully started. + // TODO: explore health endpoint perhaps instead of ready state under Admin endpoint. + Flux.fromIterable(servers).flatMap(s -> Mono.delay(Duration.ofMillis(500)).then(s.executeCommand(cmd))).subscribe(); + } + } } } } - } - } + } + } catch (Exception e) { + getLog().error("Failed to connect to Boot app", e); + } } } }; - private void connectToLaunchedBootApps() { - updateRunStateListening(); - - getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent event) { - if (PREF_LIVE_INFORMATION_AUTO_CONNECT.equals(event.getProperty())) { - updateRunStateListening(); - } - } - }); + private void listenToLaunchedBootApps() { + LocalBootDashModel localModel = (LocalBootDashModel) getModel().getSectionByTargetId(RunTargets.LOCAL.getId()); + LaunchConfRunStateTracker tracker = localModel.getLaunchConfRunStateTracker(); + tracker.addListener(RUN_STATE_LISTENER); } - private void updateRunStateListening() { + private void stopListeningToLaunchedBootApps() { LocalBootDashModel localModel = (LocalBootDashModel) getModel().getSectionByTargetId(RunTargets.LOCAL.getId()); LaunchConfRunStateTracker tracker = localModel.getLaunchConfRunStateTracker(); - if (getPreferenceStore().getBoolean(PREF_LIVE_INFORMATION_AUTO_CONNECT)) { - tracker.addListener(RUN_STATE_LISTENER); - } else { - tracker.removeListener(RUN_STATE_LISTENER); - } + tracker.removeListener(RUN_STATE_LISTENER); } } diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/prefs/BootDashPrefsPage.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/prefs/BootDashPrefsPage.java index ea2a83cd9..9aed73ee0 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/prefs/BootDashPrefsPage.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/prefs/BootDashPrefsPage.java @@ -36,7 +36,6 @@ public class BootDashPrefsPage extends FieldEditorPreferencePage implements IWor @Override protected void createFieldEditors() { Composite parent = getFieldEditorParent(); - addField(new BooleanFieldEditor(BootDashActivator.PREF_LIVE_INFORMATION_AUTO_CONNECT, "Auto Connect to launched Boot app to show Live Information", parent)); for (RunTargetType rtt : BootDashActivator.getDefault().getModel().getRunTargetTypes()) { if (rtt.supportsDeletion()) { addField(new BooleanFieldEditor(DeleteElementsAction.PREF_SKIP_CONFIRM_DELETE(rtt), "Skip Delete Element Confirmation ("+rtt.getName()+")", parent)); diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/prefs/PrefsInitializer.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/prefs/PrefsInitializer.java deleted file mode 100644 index 0da0f87f2..000000000 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/prefs/PrefsInitializer.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2022 VMware, 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 - * https://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VMware, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.eclipse.boot.dash.prefs; - -import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; -import org.eclipse.jface.preference.IPreferenceStore; -import org.springframework.ide.eclipse.boot.dash.BootDashActivator; - -public class PrefsInitializer extends AbstractPreferenceInitializer { - - public PrefsInitializer() { - } - - @Override - public void initializeDefaultPreferences() { - IPreferenceStore preferenceStore = BootDashActivator.getDefault().getPreferenceStore(); - preferenceStore.setDefault(BootDashActivator.PREF_LIVE_INFORMATION_AUTO_CONNECT, true); - } - -} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootLaunchConfigurationDelegate.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootLaunchConfigurationDelegate.java index cd8682cfa..02c0fb6e0 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootLaunchConfigurationDelegate.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootLaunchConfigurationDelegate.java @@ -134,6 +134,9 @@ public class BootLaunchConfigurationDelegate extends AbstractBootLaunchConfigura public static final String SPRING_PROJECT_NAME_ATTRIBUTE = "spring.boot.project.name"; + public static final String AUTO_CONNECT = "spring.boot.auto-connect"; + public static final boolean DEFAULT_AUTO_CONNECT = true; + // Preference for Eclipse ANSI Console support. // See org.eclipse.ui.internal.console.ansi.preferences.AnsiConsolePreferenceConstants // Because this class is only available in Eclipse 4.25 and higher, we cannot add a @@ -363,6 +366,7 @@ public class BootLaunchConfigurationDelegate extends AbstractBootLaunchConfigura setMainType(wc, mainType); } setEnableJMX(wc, DEFAULT_ENABLE_JMX); + setAutoConnect(wc, false); setEnableLiveBeanSupport(wc, DEFAULT_ENABLE_LIVE_BEAN_SUPPORT()); setEnableLifeCycle(wc, DEFAULT_ENABLE_LIFE_CYCLE); setTerminationTimeout(wc,""+DEFAULT_TERMINATION_TIMEOUT); @@ -442,6 +446,19 @@ public class BootLaunchConfigurationDelegate extends AbstractBootLaunchConfigura return ""; } + public static boolean getAutoConnect(ILaunchConfiguration conf) { + try { + return conf.getAttribute(AUTO_CONNECT, DEFAULT_AUTO_CONNECT); + } catch (CoreException e) { + Log.log(e); + } + return false; + } + + public static void setAutoConnect(ILaunchConfigurationWorkingCopy conf, boolean autoConnect) { + conf.setAttribute(AUTO_CONNECT, autoConnect); + } + public static void setEnableLiveBeanSupport(ILaunchConfigurationWorkingCopy conf, boolean value) { conf.setAttribute(ENABLE_LIVE_BEAN_SUPPORT, value); } diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootLaunchUIModel.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootLaunchUIModel.java index 79347a1f4..a3e85b628 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootLaunchUIModel.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootLaunchUIModel.java @@ -71,6 +71,7 @@ public class BootLaunchUIModel { public final LaunchTabSelectionModel enableDebug; public final EnableJmxFeaturesModel enableJmx; public final LaunchTabSelectionModel hideFromDash; + public final LaunchTabSelectionModel autoConnect; public final LaunchTabSelectionModel ansiConsoleOutput; public final LaunchTabSelectionModel fastStartup; public final LaunchTabSelectionModel useThinWrapper; @@ -82,6 +83,7 @@ public class BootLaunchUIModel { enableDebug = CheckboxLaunchTabModel.create(ENABLE_DEBUG_OUTPUT, DEFAULT_ENABLE_DEBUG_OUTPUT); enableJmx = new EnableJmxFeaturesModel(); hideFromDash = CheckboxLaunchTabModel.create(HIDE_FROM_BOOT_DASH, DEFAULT_HIDE_FROM_BOOT_DASH); + autoConnect = CheckboxLaunchTabModel.create(AUTO_CONNECT, DEFAULT_AUTO_CONNECT); ansiConsoleOutput = CheckboxLaunchTabModel.create(ANSI_CONSOLE_OUTPUT, BootLaunchConfigurationDelegate.supportsAnsiConsoleOutput()); fastStartup = CheckboxLaunchTabModel.create(FAST_STARTUP, BootActivator.getDefault().getPreferenceStore() .getBoolean(BootPreferences.PREF_BOOT_FAST_STARTUP_DEFAULT)); diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootMainTab.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootMainTab.java index ae5ec28a2..65e98d0ee 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootMainTab.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.launch/src/org/springframework/ide/eclipse/boot/launch/BootMainTab.java @@ -54,6 +54,7 @@ public class BootMainTab extends LaunchConfigurationTabWithSections implements I jvmArgsSections.add(new EnableDebugSection(this, model.enableDebug)); jvmArgsSections.add(new HideFromBootDashSection(this, model.hideFromDash)); jvmArgsSections.add(new FastStartupLaunchTabSection(this, model.fastStartup)); + jvmArgsSections.add(new DelegatingLaunchConfigurationTabSection(this, model.autoConnect, new CheckboxSection(this, model.autoConnect, "Auto-connect to fetch Live Data"))); /* * Show UI for enabling/disabling ANSI console output only if * IDE supports ANSI console output