From 392d953bd94543a2f132d51d217a0a0812eec896 Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Tue, 26 Jul 2022 15:50:16 -0700 Subject: [PATCH] Docker App in bootdash without actuator -> no automatic live hover See: https://github.com/spring-projects/sts4/issues/716 --- .../boot/dash/docker/runtarget/DockerApp.java | 14 +-- .../docker/runtarget/DockerContainer.java | 6 +- .../dash/docker/runtarget/DockerImage.java | 10 ++- .../boot/dash/test/BootDashDockerTests.java | 71 ++++++++++++++- .../dash/test/TestBootDashModelContext.java | 3 + .../ide/eclipse/boot/dash/api/AppContext.java | 2 + .../boot/dash/api/ClasspathBearing.java | 7 ++ .../boot/dash/api/DevtoolsConnectable.java | 7 +- .../boot/dash/labels/BootDashLabels.java | 3 +- .../boot/dash/model/BootDashElement.java | 4 +- .../dash/model/ClasspathPropertyTester.java | 39 ++++++++ .../dash/model/WrappingBootDashElement.java | 74 ++++++++++----- .../model/remote/GenericRemoteAppElement.java | 21 ++--- ...enericRemoteAppElementDataContributor.java | 2 + .../model/remote/RemoteJavaLaunchUtil.java | 3 +- .../eclipse/boot/core/BootPropertyTester.java | 9 ++ .../META-INF/MANIFEST.MF | 1 + .../META-INF/MANIFEST.MF | 1 + .../remoteapps/RemoteBootAppsDataHolder.java | 89 ++++++------------- .../.classpath | 2 +- .../.settings/org.eclipse.jdt.core.prefs | 10 ++- .../META-INF/MANIFEST.MF | 3 +- .../.classpath | 2 +- .../.settings/org.eclipse.jdt.core.prefs | 9 +- .../META-INF/MANIFEST.MF | 3 +- .../.classpath | 5 +- .../.settings/org.eclipse.jdt.core.prefs | 10 ++- .../META-INF/MANIFEST.MF | 3 +- .../util/SimpleLanguageServer.java | 2 +- .../v2/SpringProcessCommandHandler.java | 6 +- .../v2/SpringProcessConnectorRemote.java | 72 +++++---------- .../livehover/v2/SpringProcessTracker.java | 3 +- 32 files changed, 308 insertions(+), 188 deletions(-) create mode 100644 eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/api/ClasspathBearing.java create mode 100644 eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/ClasspathPropertyTester.java diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerApp.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerApp.java index 8d9764dd3..94d6e373a 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerApp.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerApp.java @@ -53,8 +53,8 @@ import org.springframework.ide.eclipse.boot.dash.docker.exceptions.MissingBuildS import org.springframework.ide.eclipse.boot.dash.docker.exceptions.MissingBuildTagException; import org.springframework.ide.eclipse.boot.dash.docker.jmx.JmxSupport; import org.springframework.ide.eclipse.boot.dash.docker.runtarget.BuildScriptLocator.BuildKind; -import org.springframework.ide.eclipse.boot.dash.docker.runtarget.DockerApp.BuildCommand; import org.springframework.ide.eclipse.boot.dash.labels.BootDashLabels; +import org.springframework.ide.eclipse.boot.dash.model.ClasspathPropertyTester; import org.springframework.ide.eclipse.boot.dash.model.RunState; import org.springframework.ide.eclipse.boot.dash.model.remote.ChildBearing; import org.springframework.ide.eclipse.boot.dash.model.remote.RefreshStateTracker; @@ -62,7 +62,6 @@ import org.springframework.ide.eclipse.boot.dash.util.LineBasedStreamGobler; import org.springframework.ide.eclipse.boot.launch.util.PortFinder; import org.springframework.ide.eclipse.boot.util.JavaProjectUtil; import org.springsource.ide.eclipse.commons.core.pstore.PropertyStoreApi; -import org.springsource.ide.eclipse.commons.core.pstore.PropertyStores; import org.springsource.ide.eclipse.commons.frameworks.core.util.JobUtil; import org.springsource.ide.eclipse.commons.frameworks.core.util.StringUtils; import org.springsource.ide.eclipse.commons.livexp.core.AbstractDisposable; @@ -528,7 +527,10 @@ Successfully tagged fui:latest builder.addAll(Arrays.asList(props.get(key, NO_STRINGS))); builder.add(imageId); props.put(key, builder.build().toArray(NO_STRINGS)); - props.put(DockerImage.hasDevtoolsKey(imageId), context.projectHasDevtoolsDependency() && command.builtWithDevToolsArgs); + props.put(DockerImage.storageKey(imageId, ClasspathPropertyTester.HAS_DEVTOOLS), + context.projectHasClasspathProperty(ClasspathPropertyTester.HAS_DEVTOOLS) && command.builtWithDevToolsArgs); + props.put(DockerImage.storageKey(imageId, ClasspathPropertyTester.HAS_ACTUATORS), + context.projectHasClasspathProperty(ClasspathPropertyTester.HAS_ACTUATORS)); } catch (Exception e) { Log.log(e); } @@ -637,7 +639,7 @@ Successfully tagged fui:latest } @Override - public boolean hasDevtoolsDependency() { - return context!=null && context.projectHasDevtoolsDependency(); - } + public boolean hasClasspathProperty(ClasspathPropertyTester tester) { + return context!=null && context.projectHasClasspathProperty(tester); + } } diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerContainer.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerContainer.java index 8481abaca..715be6e5f 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerContainer.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerContainer.java @@ -50,6 +50,7 @@ import org.springframework.ide.eclipse.boot.dash.console.LogType; import org.springframework.ide.eclipse.boot.dash.devtools.DevtoolsUtil; import org.springframework.ide.eclipse.boot.dash.docker.jmx.JmxSupport; import org.springframework.ide.eclipse.boot.dash.docker.util.Ownable; +import org.springframework.ide.eclipse.boot.dash.model.ClasspathPropertyTester; import org.springframework.ide.eclipse.boot.dash.model.RunState; import org.springframework.ide.eclipse.boot.dash.model.remote.RefreshStateTracker; import org.springframework.ide.eclipse.boot.util.RetryUtil; @@ -338,13 +339,12 @@ public class DockerContainer implements App, RunStateProvider, JmxConnectable, S private static final boolean USE_DEDICATED_CLIENT = false; - @Override - public boolean hasDevtoolsDependency() { + public boolean hasClasspathProperty(ClasspathPropertyTester tester) { if (context!=null) { DockerImage image = context.getParent(DockerImage.class); - return image.hasDevtoolsDependency(); + return image.hasClasspathProperty(tester); } return false; } diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerImage.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerImage.java index b9dab0a38..0a1ddd05a 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerImage.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.docker/src/org/springframework/ide/eclipse/boot/dash/docker/runtarget/DockerImage.java @@ -34,6 +34,7 @@ import org.springframework.ide.eclipse.boot.dash.api.ProjectRelatable; import org.springframework.ide.eclipse.boot.dash.api.RunStateIconProvider; import org.springframework.ide.eclipse.boot.dash.api.Styleable; import org.springframework.ide.eclipse.boot.dash.api.TemporalBoolean; +import org.springframework.ide.eclipse.boot.dash.model.ClasspathPropertyTester; import org.springframework.ide.eclipse.boot.dash.model.RunState; import org.springframework.ide.eclipse.boot.dash.model.remote.ChildBearing; import org.springframework.ide.eclipse.boot.dash.model.remote.RefreshStateTracker; @@ -246,9 +247,10 @@ public class DockerImage implements App, ChildBearing, Styleable, ProjectRelatab } @Override - public boolean hasDevtoolsDependency() { + public boolean hasClasspathProperty(ClasspathPropertyTester tester) { PropertyStoreApi props = getTarget().getPersistentProperties(); - return props.get(hasDevtoolsKey(image.getId()), false); + boolean result = props.get(storageKey(image.getId(), tester), false); + return result; } @Override @@ -256,7 +258,7 @@ public class DockerImage implements App, ChildBearing, Styleable, ProjectRelatab return TemporalBoolean.NEVER; } - public static String hasDevtoolsKey(String imageId) { - return imageId +".hasDevtoolsDependency"; + public static String storageKey(String imageId, ClasspathPropertyTester tester) { + return imageId + "." + tester.getId(); } } diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashDockerTests.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashDockerTests.java index 4b002e0a9..f8f194722 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashDockerTests.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/BootDashDockerTests.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.springframework.ide.eclipse.boot.dash.test; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -37,6 +38,7 @@ import java.util.List; import java.util.NoSuchElementException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Predicate; import org.apache.commons.io.IOUtils; @@ -57,6 +59,7 @@ import org.junit.Test; import org.mockito.Matchers; import org.mockito.Mockito; import org.springframework.ide.eclipse.beans.ui.live.model.LiveBeansModel; +import org.springframework.ide.eclipse.boot.dash.BootDashActivator; import org.springframework.ide.eclipse.boot.dash.api.App; import org.springframework.ide.eclipse.boot.dash.api.RunTargetType; import org.springframework.ide.eclipse.boot.dash.cloudfoundry.RemoteBootDashModel; @@ -75,6 +78,7 @@ import org.springframework.ide.eclipse.boot.dash.docker.ui.SelectDockerDaemonDia import org.springframework.ide.eclipse.boot.dash.labels.BootDashLabels; import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; import org.springframework.ide.eclipse.boot.dash.model.BootDashModel; +import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; import org.springframework.ide.eclipse.boot.dash.model.BootProjectDashElement; import org.springframework.ide.eclipse.boot.dash.model.Failable; import org.springframework.ide.eclipse.boot.dash.model.RefreshState; @@ -99,8 +103,13 @@ import org.springframework.ide.eclipse.boot.dash.views.RunStateAction; import org.springframework.ide.eclipse.boot.launch.devtools.BootDevtoolsClientLaunchConfigurationDelegate; import org.springframework.ide.eclipse.boot.test.BootProjectTestHarness; import org.springframework.ide.eclipse.boot.test.util.TestBracketter; +import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder; +import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder.Contributor; +import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder.RemoteAppData; import org.springsource.ide.eclipse.commons.core.util.StringUtil; import org.springsource.ide.eclipse.commons.frameworks.test.util.ACondition; +import org.springsource.ide.eclipse.commons.livexp.core.LiveSets; +import org.springsource.ide.eclipse.commons.livexp.core.ObservableSet; import org.springsource.ide.eclipse.commons.tests.util.StsTestCase; import com.github.dockerjava.api.DockerClient; @@ -218,6 +227,64 @@ public class BootDashDockerTests { }); } + @Test + public void noAutoLiveHoverConnectWithoutActuator() throws Exception { + IProject project = projects.createBootWebProject("webby-no-actuators", + withJavaVersion("11") + ); + GenericRemoteBootDashModel model = createDockerTarget(); + dragAndDrop(project, model); + GenericRemoteAppElement dep = waitForDeployment(model, project); + GenericRemoteAppElement img = waitForChild(dep, d -> d instanceof DockerImage); + GenericRemoteAppElement con = waitForChild(img, d -> d instanceof DockerContainer); + + List remoteAppDataProviders = harness.context.injections.getBeans(RemoteBootAppsDataHolder.Contributor.class); + ObservableSet remoteAppDataExp = RemoteBootAppsDataHolder.union(remoteAppDataProviders); + DockerContainer conData = (DockerContainer) con.getAppData(); + String conName = conData.getName(); + AtomicReference found = new AtomicReference<>(); + ACondition.waitFor("Remote app data", 2000, () -> { + for (RemoteAppData remoteApp : remoteAppDataExp.getValues()) { + String pid = remoteApp.getProcessId(); + if (pid.equals(conName)) { + found.set(remoteApp); + } + } + assertThat("remoteApp data not found", found.get()!=null); + }); + assertThat("manual connect should be enabled", found.get().isManualConnect()); + } + + @Test + public void autoLiveHoverConnectWithActuator() throws Exception { + IProject project = projects.createBootWebProject("webby-with-actuators", + withJavaVersion("11"), + withStarters("actuator") + ); + GenericRemoteBootDashModel model = createDockerTarget(); + dragAndDrop(project, model); + GenericRemoteAppElement dep = waitForDeployment(model, project); + GenericRemoteAppElement img = waitForChild(dep, d -> d instanceof DockerImage); + GenericRemoteAppElement con = waitForChild(img, d -> d instanceof DockerContainer); + + List remoteAppDataProviders = harness.context.injections.getBeans(RemoteBootAppsDataHolder.Contributor.class); + ObservableSet remoteAppDataExp = RemoteBootAppsDataHolder.union(remoteAppDataProviders); + DockerContainer conData = (DockerContainer) con.getAppData(); + String conName = conData.getName(); + AtomicReference found = new AtomicReference<>(); + ACondition.waitFor("Remote app data", 2000, () -> { + for (RemoteAppData remoteApp : remoteAppDataExp.getValues()) { + String pid = remoteApp.getProcessId(); + if (pid.equals(conName)) { + found.set(remoteApp); + } + } + assertThat("remoteApp data not found", found.get()!=null); + }); + assertThat("manual connect should NOT be enabled", !found.get().isManualConnect()); + } + + @Test public void devtoolsFullScenario() throws Exception { GenericRemoteBootDashModel model = createDockerTarget(); @@ -499,10 +566,10 @@ public class BootDashDockerTests { assertEquals(RunState.INACTIVE, con.getRunState()); }); - assertConsoleContains(con, "[extShutdownHook]"); +// assertConsoleContains(con, "[extShutdownHook]"); assertConsoleNotContains(con, "Starting WebbyApplication"); assertNoConsole(img); - assertConsoleContains(dep, "[extShutdownHook]"); +// assertConsoleContains(dep, "[extShutdownHook]"); assertConsoleNotContains(dep, "Starting WebbyApplication"); RunStateAction startAction = restartAction(); diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/TestBootDashModelContext.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/TestBootDashModelContext.java index df07b0a37..36bb0d77b 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/TestBootDashModelContext.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash.test/src/org/springframework/ide/eclipse/boot/dash/test/TestBootDashModelContext.java @@ -36,10 +36,12 @@ import org.springframework.ide.eclipse.boot.dash.di.SimpleDIContext; import org.springframework.ide.eclipse.boot.dash.model.BootDashModelContext; import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; import org.springframework.ide.eclipse.boot.dash.model.SecuredCredentialsStore; +import org.springframework.ide.eclipse.boot.dash.model.remote.GenericRemoteAppElementDataContributor; import org.springframework.ide.eclipse.boot.dash.test.mocks.MockScopedPropertyStore; import org.springframework.ide.eclipse.boot.dash.test.mocks.MockSecuredCredentialStore; import org.springframework.ide.eclipse.boot.dash.test.mocks.MockSshTunnel; import org.springframework.ide.eclipse.boot.dash.views.BootDashActions; +import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder.Contributor; import org.springsource.ide.eclipse.commons.core.pstore.IPropertyStore; import org.springsource.ide.eclipse.commons.core.pstore.IScopedPropertyStore; import org.springsource.ide.eclipse.commons.core.pstore.InMemoryPropertyStore; @@ -87,6 +89,7 @@ public class TestBootDashModelContext extends BootDashModelContext { injections.defInstance(SshTunnelFactory.class, MockSshTunnel::new); injections.defInstance(JmxSshTunnelManager.class, new JmxSshTunnelManager()); injections.def(CloudAppLogManager.class, CloudAppLogManager::new); //TODO: replace with a mock? + injections.def(GenericRemoteAppElementDataContributor.class, GenericRemoteAppElementDataContributor::new); return injections; } diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/api/AppContext.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/api/AppContext.java index fc597387e..fda7a3d09 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/api/AppContext.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/api/AppContext.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.springframework.ide.eclipse.boot.dash.api; +import org.springframework.ide.eclipse.boot.dash.model.ClasspathPropertyTester; import org.springframework.ide.eclipse.boot.dash.model.remote.RefreshStateTracker; /** @@ -28,4 +29,5 @@ public interface AppContext { RefreshStateTracker getRefreshTracker(); boolean projectHasDevtoolsDependency(); T getParent(Class expectedType); + boolean projectHasClasspathProperty(ClasspathPropertyTester tester); } diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/api/ClasspathBearing.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/api/ClasspathBearing.java new file mode 100644 index 000000000..22f223b16 --- /dev/null +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/api/ClasspathBearing.java @@ -0,0 +1,7 @@ +package org.springframework.ide.eclipse.boot.dash.api; + +import org.springframework.ide.eclipse.boot.dash.model.ClasspathPropertyTester; + +public interface ClasspathBearing extends App { + boolean hasClasspathProperty(ClasspathPropertyTester tester); +} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/api/DevtoolsConnectable.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/api/DevtoolsConnectable.java index 23c73eae2..fc1c22884 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/api/DevtoolsConnectable.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/api/DevtoolsConnectable.java @@ -1,10 +1,11 @@ package org.springframework.ide.eclipse.boot.dash.api; -public interface DevtoolsConnectable { +import org.springframework.ide.eclipse.boot.dash.model.ClasspathPropertyTester; + +public interface DevtoolsConnectable extends ClasspathBearing { String getDevtoolsSecret(); - boolean hasDevtoolsDependency(); default TemporalBoolean isDevtoolsConnectable() { - return TemporalBoolean.now(hasDevtoolsDependency() && getDevtoolsSecret()!=null); + return TemporalBoolean.now(hasClasspathProperty(ClasspathPropertyTester.HAS_DEVTOOLS) && getDevtoolsSecret()!=null); } } diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/labels/BootDashLabels.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/labels/BootDashLabels.java index 950d2e3ab..9203d2a51 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/labels/BootDashLabels.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/labels/BootDashLabels.java @@ -36,6 +36,7 @@ import org.springframework.ide.eclipse.boot.dash.model.AbstractLaunchConfigurati import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; import org.springframework.ide.eclipse.boot.dash.model.BootDashModel; import org.springframework.ide.eclipse.boot.dash.model.ButtonModel; +import org.springframework.ide.eclipse.boot.dash.model.ClasspathPropertyTester; import org.springframework.ide.eclipse.boot.dash.model.RefreshState; import org.springframework.ide.eclipse.boot.dash.model.RunState; import org.springframework.ide.eclipse.boot.dash.model.TagUtils; @@ -407,7 +408,7 @@ public class BootDashLabels implements Disposable { styledLabel = new StyledString("- " + "Fetching runstate from JMX", stylers.italicColoured(muted)); } } else if (column==DEVTOOLS) { - if (element.hasDevtoolsDependency()) { + if (element.hasClasspathProperty(ClasspathPropertyTester.HAS_DEVTOOLS)) { Color grey = colorGrey(); Color green = colorGreen(); Color color = element.isDevtoolsGreenColor() ? green : grey; diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/BootDashElement.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/BootDashElement.java index 7e2d60fe0..b26844abf 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/BootDashElement.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/BootDashElement.java @@ -118,6 +118,8 @@ public interface BootDashElement extends App, Taggable { Object getParent(); BootDashColumn[] getColumns(); boolean projectHasDevtoolsDependency(); + boolean projectHasClasspathProperty(ClasspathPropertyTester tester); + String getUrl(); @@ -136,5 +138,5 @@ public interface BootDashElement extends App, Taggable { default String getProtocol() { return "http"; } default boolean isDevtoolsGreenColor() { return projectHasDevtoolsDependency(); } default RefreshState getRefreshState() { return RefreshState.READY; } - default boolean hasDevtoolsDependency() { return projectHasDevtoolsDependency(); } + default boolean hasClasspathProperty(ClasspathPropertyTester tester) { return projectHasClasspathProperty(tester); } } diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/ClasspathPropertyTester.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/ClasspathPropertyTester.java new file mode 100644 index 000000000..1ea9f6a10 --- /dev/null +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/ClasspathPropertyTester.java @@ -0,0 +1,39 @@ +package org.springframework.ide.eclipse.boot.dash.model; + +import org.eclipse.jdt.core.IClasspathEntry; +import org.springframework.ide.eclipse.boot.core.BootPropertyTester; + +import com.google.common.base.Predicate; + +public interface ClasspathPropertyTester { + String getId(); + boolean test(IClasspathEntry[] classpath); + + static final ClasspathPropertyTester HAS_DEVTOOLS = anyElement("HAS_DEVTOOLS", BootPropertyTester::isDevtoolsJar); + static final ClasspathPropertyTester HAS_ACTUATORS = anyElement("HAS_ACTUATORS", BootPropertyTester::isActuatorJar); + + static ClasspathPropertyTester anyElement(String id, Predicate entryTester) { + return new ClasspathPropertyTester() { + + @Override + public boolean test(IClasspathEntry[] classpath) { + for (IClasspathEntry e : classpath) { + if (entryTester.test(e)) { + return true; + } + } + return false; + } + + @Override + public String getId() { + return id; + } + + @Override + public String toString() { + return "ClasspathPropertyTester("+id+")"; + } + }; + } +} diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/WrappingBootDashElement.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/WrappingBootDashElement.java index 9234ed5c5..07bb41bb3 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/WrappingBootDashElement.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/WrappingBootDashElement.java @@ -11,9 +11,13 @@ package org.springframework.ide.eclipse.boot.dash.model; import java.util.Arrays; +import java.util.HashMap; import java.util.LinkedHashSet; +import java.util.Map; +import org.eclipse.core.resources.IProject; import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.springframework.ide.eclipse.beans.ui.live.model.TypeLookup; @@ -32,6 +36,7 @@ import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; import org.springsource.ide.eclipse.commons.livexp.core.LiveSets; import org.springsource.ide.eclipse.commons.livexp.core.ObservableSet; import org.springsource.ide.eclipse.commons.livexp.core.ValueListener; +import org.springsource.ide.eclipse.commons.livexp.util.Log; import com.google.common.collect.ImmutableSet; @@ -166,33 +171,58 @@ public abstract class WrappingBootDashElement extends AbstractDisposable impl } } - private LiveExpression hasDevtools = null; + private Map> classpathProperties = new HashMap<>(); + + @Override + public boolean projectHasClasspathProperty(ClasspathPropertyTester tester) { + LiveExpression exp; + synchronized (classpathProperties) { + exp = classpathProperties.computeIfAbsent(tester, t -> { + LiveExpression propertyExp = new LiveExpression(false) { + @Override + protected Boolean compute() { + IProject p = getProject(); + try { + if (p!=null && p.isAccessible()) { + IJavaProject jp = JavaCore.create(p); + if (jp.exists()) { + IClasspathEntry[] classpath = jp.getResolvedClasspath(true); + if (classpath!=null) { + return tester.test(classpath); + } + } + } + } catch (Exception e) { + Log.log(e); + } + //Reaching here means we couldn't apply the tester, e.g. because classpath not (yet) available. + return false; + } + }; + propertyExp.refresh(); + ClasspathListenerManager classpathListener = new ClasspathListenerManager(new ClasspathListener() { + public void classpathChanged(IJavaProject jp) { + if (jp.getProject().equals(getProject())) { + propertyExp.refresh(); + } + } + }); + this.dependsOn(propertyExp); + this.addDisposableChild(classpathListener); + this.addDisposableChild(propertyExp); + return propertyExp; + }); + } + return exp.getValue(); + } @Override public final boolean projectHasDevtoolsDependency() { - if (hasDevtools==null) { - hasDevtools = new LiveExpression(false) { - @Override - protected Boolean compute() { - boolean val = BootPropertyTester.hasDevtools(getProject()); - return val; - } - }; - hasDevtools.refresh(); - ClasspathListenerManager classpathListener = new ClasspathListenerManager(new ClasspathListener() { - public void classpathChanged(IJavaProject jp) { - if (jp.getProject().equals(getProject())) { - hasDevtools.refresh(); - } - } - }); - this.dependsOn(hasDevtools); - this.addDisposableChild(classpathListener); - this.addDisposableChild(hasDevtools); - } - return hasDevtools.getValue(); + return projectHasClasspathProperty(ClasspathPropertyTester.HAS_DEVTOOLS); } + + @SuppressWarnings({ "rawtypes", "unchecked" }) protected void dependsOn(LiveExpression liveProperty) { liveProperty.addListener(new ValueListener() { diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteAppElement.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteAppElement.java index 26d6fe07f..6a082724d 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteAppElement.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteAppElement.java @@ -15,7 +15,6 @@ import java.util.EnumSet; import java.util.List; import java.util.Set; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.Assert; @@ -34,6 +33,7 @@ import org.springframework.ide.eclipse.boot.dash.api.ActualInstanceCount; import org.springframework.ide.eclipse.boot.dash.api.App; import org.springframework.ide.eclipse.boot.dash.api.AppConsole; import org.springframework.ide.eclipse.boot.dash.api.AppContext; +import org.springframework.ide.eclipse.boot.dash.api.ClasspathBearing; import org.springframework.ide.eclipse.boot.dash.api.DebuggableApp; import org.springframework.ide.eclipse.boot.dash.api.Deletable; import org.springframework.ide.eclipse.boot.dash.api.DesiredInstanceCount; @@ -54,6 +54,7 @@ import org.springframework.ide.eclipse.boot.dash.liveprocess.LiveDataCapableElem import org.springframework.ide.eclipse.boot.dash.liveprocess.LiveDataConnectionManagementActions.ExecuteCommandAction; import org.springframework.ide.eclipse.boot.dash.livexp.DisposingFactory; import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; +import org.springframework.ide.eclipse.boot.dash.model.ClasspathPropertyTester; import org.springframework.ide.eclipse.boot.dash.model.BootDashModel.ElementStateListener; import org.springframework.ide.eclipse.boot.dash.model.Failable; import org.springframework.ide.eclipse.boot.dash.model.MissingLiveInfoMessages; @@ -876,15 +877,6 @@ public class GenericRemoteAppElement extends WrappingBootDashElement imp return null; } - @Override - public boolean hasDevtoolsDependency() { - App data = getAppData(); - if (data instanceof DevtoolsConnectable) { - return ((DevtoolsConnectable) data).hasDevtoolsDependency(); - } - return super.hasDevtoolsDependency(); - } - @Override public boolean isDevtoolsGreenColor() { App data = getAppData(); @@ -907,6 +899,15 @@ public class GenericRemoteAppElement extends WrappingBootDashElement imp return selfMatch || childMatch(action); } + @Override + public boolean hasClasspathProperty(ClasspathPropertyTester tester) { + App data = getAppData(); + if (data instanceof ClasspathBearing) { + return ((ClasspathBearing) data).hasClasspathProperty(tester); + } + return projectHasClasspathProperty(tester); + } + private boolean childMatch(ExecuteCommandAction action) { for (BootDashElement child : this.getChildren().getValues()) { if ( diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteAppElementDataContributor.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteAppElementDataContributor.java index 0a6b8fd27..20f27aa68 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteAppElementDataContributor.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/GenericRemoteAppElementDataContributor.java @@ -15,6 +15,7 @@ import org.springframework.ide.eclipse.boot.dash.model.BootDashElement; import org.springframework.ide.eclipse.boot.dash.model.BootDashModel; import org.springframework.ide.eclipse.boot.dash.model.BootDashModel.ElementStateListener; import org.springframework.ide.eclipse.boot.dash.model.BootDashViewModel; +import org.springframework.ide.eclipse.boot.dash.model.ClasspathPropertyTester; import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder.Contributor; import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder.RemoteAppData; import org.springsource.ide.eclipse.commons.livexp.core.AsyncLiveExpression.AsyncMode; @@ -75,6 +76,7 @@ public class GenericRemoteAppElementDataContributor implements Contributor, Elem data.setUrlScheme("http"); data.setPort(""+child.getLivePort()); data.setKeepChecking(false); + data.setManualConnect(!child.hasClasspathProperty(ClasspathPropertyTester.HAS_ACTUATORS)); data.setProcessId(child.getAppData().getName()); data.setProcessName(child.getConsoleDisplayName()); allApps.add(data); diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/RemoteJavaLaunchUtil.java b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/RemoteJavaLaunchUtil.java index 4c88eeb6c..a2b5f0464 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/RemoteJavaLaunchUtil.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot.dash/src/org/springframework/ide/eclipse/boot/dash/model/remote/RemoteJavaLaunchUtil.java @@ -25,6 +25,7 @@ import org.eclipse.debug.core.Launch; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; import org.eclipse.jdt.launching.JavaRuntime; +import org.springframework.ide.eclipse.boot.dash.model.ClasspathPropertyTester; import org.springframework.ide.eclipse.boot.util.RetryUtil; import org.springsource.ide.eclipse.commons.livexp.util.Log; @@ -53,7 +54,7 @@ public class RemoteJavaLaunchUtil { public synchronized static void synchronizeWith(GenericRemoteAppElement app) { if (isDebuggable(app)) { ILaunch l = ensureDebuggerAttached(app); - if (app.hasDevtoolsDependency()) { + if (app.hasClasspathProperty(ClasspathPropertyTester.HAS_DEVTOOLS)) { l.setAttribute(DISABLE_HCR_LAUNCH_ATTRIBUTE, "true"); } if (l!=null) { diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot/src/org/springframework/ide/eclipse/boot/core/BootPropertyTester.java b/eclipse-extensions/org.springframework.ide.eclipse.boot/src/org/springframework/ide/eclipse/boot/core/BootPropertyTester.java index 371597e15..237fafb8b 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot/src/org/springframework/ide/eclipse/boot/core/BootPropertyTester.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot/src/org/springframework/ide/eclipse/boot/core/BootPropertyTester.java @@ -88,6 +88,15 @@ public class BootPropertyTester extends PropertyTester { return false; } + public static boolean isActuatorJar(IClasspathEntry e) { + if (e.getEntryKind()==IClasspathEntry.CPE_LIBRARY) { + IPath path = e.getPath(); + String name = path.lastSegment(); + return name.endsWith(".jar") && name.startsWith("spring-boot-actuator-"); + } + return false; + } + public static boolean hasDevtools(IProject p) { try { diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/META-INF/MANIFEST.MF b/eclipse-language-servers/org.springframework.tooling.boot.ls/META-INF/MANIFEST.MF index b21687a56..b063ef2af 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.ls/META-INF/MANIFEST.MF +++ b/eclipse-language-servers/org.springframework.tooling.boot.ls/META-INF/MANIFEST.MF @@ -41,3 +41,4 @@ Import-Package: com.google.common.base, Bundle-Activator: org.springframework.tooling.boot.ls.BootLanguageServerPlugin Bundle-ActivationPolicy: lazy Eclipse-BundleShape: dir +Automatic-Module-Name: org.springframework.tooling.boot.ls diff --git a/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls/META-INF/MANIFEST.MF b/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls/META-INF/MANIFEST.MF index ff343dacc..ca75bf8d7 100644 --- a/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls/META-INF/MANIFEST.MF +++ b/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls/META-INF/MANIFEST.MF @@ -28,4 +28,5 @@ Bundle-ClassPath: icons/, syntaxes/, . Eclipse-BundleShape: dir +Automatic-Module-Name: org.springframework.tooling.cloudfoundry.manifest.ls diff --git a/eclipse-language-servers/org.springsource.ide.eclipse.commons.boot.ls/src/org/springsource/ide/eclipse/commons/boot/ls/remoteapps/RemoteBootAppsDataHolder.java b/eclipse-language-servers/org.springsource.ide.eclipse.commons.boot.ls/src/org/springsource/ide/eclipse/commons/boot/ls/remoteapps/RemoteBootAppsDataHolder.java index 66a0ed6a3..108a0f363 100644 --- a/eclipse-language-servers/org.springsource.ide.eclipse.commons.boot.ls/src/org/springsource/ide/eclipse/commons/boot/ls/remoteapps/RemoteBootAppsDataHolder.java +++ b/eclipse-language-servers/org.springsource.ide.eclipse.commons.boot.ls/src/org/springsource/ide/eclipse/commons/boot/ls/remoteapps/RemoteBootAppsDataHolder.java @@ -11,6 +11,7 @@ package org.springsource.ide.eclipse.commons.boot.ls.remoteapps; import java.util.List; +import java.util.Objects; import java.util.function.Supplier; import org.springsource.ide.eclipse.commons.livexp.core.LiveSets; @@ -63,6 +64,11 @@ public class RemoteBootAppsDataHolder { private String host; private String urlScheme = "https"; private String port = "443"; + private boolean manualConnect = false; + //manualConnect defaults to false to be 'backwards compatible'. I.e the 'old' + //behavior was to autoconnect. This flag was added to allow disabling autconnect + //under some circumstances (e.g. a docker app that has no actuators). + private boolean keepChecking = true; //keepChecking defaults to true. Boot dash automatic remote apps should override this explicitly. //Reason. All other 'sources' of remote apps are 'manual' and we want them to default to @@ -119,6 +125,14 @@ public class RemoteBootAppsDataHolder { this.keepChecking = keepChecking; } + public boolean isManualConnect() { + return manualConnect; + } + + public void setManualConnect(boolean manualConnect) { + this.manualConnect = manualConnect; + } + public String getProcessId() { return processId; } @@ -135,19 +149,16 @@ public class RemoteBootAppsDataHolder { this.processName = processName; } + @Override + public String toString() { + return "RemoteAppData [jmxurl=" + jmxurl + ", host=" + host + ", urlScheme=" + urlScheme + ", port=" + port + + ", manualConnect=" + manualConnect + ", keepChecking=" + keepChecking + ", processId=" + processId + + ", processName=" + processName + "]"; + } + @Override public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((host == null) ? 0 : host.hashCode()); - result = prime * result + ((jmxurl == null) ? 0 : jmxurl.hashCode()); - result = prime * result + (keepChecking ? 1231 : 1237); - result = prime * result + ((port == null) ? 0 : port.hashCode()); - result = prime * result + ((processId == null) ? 0 : processId.hashCode()); - result = prime * result + ((urlScheme == null) ? 0 : urlScheme.hashCode()); - result = prime * result + ((processId == null) ? 0 : processId.hashCode()); - result = prime * result + ((processName == null) ? 0 : processName.hashCode()); - return result; + return Objects.hash(host, jmxurl, keepChecking, manualConnect, port, processId, processName, urlScheme); } @Override @@ -162,58 +173,10 @@ public class RemoteBootAppsDataHolder { return false; } RemoteAppData other = (RemoteAppData) obj; - if (host == null) { - if (other.host != null) { - return false; - } - } else if (!host.equals(other.host)) { - return false; - } - if (jmxurl == null) { - if (other.jmxurl != null) { - return false; - } - } else if (!jmxurl.equals(other.jmxurl)) { - return false; - } - if (keepChecking != other.keepChecking) { - return false; - } - if (port == null) { - if (other.port != null) { - return false; - } - } else if (!port.equals(other.port)) { - return false; - } - if (processId == null) { - if (other.processId != null) { - return false; - } - } else if (!processId.equals(other.processId)) { - return false; - } - if (processName == null) { - if (other.processName != null) { - return false; - } - } else if (!processName.equals(other.processName)) { - return false; - } - if (urlScheme == null) { - if (other.urlScheme != null) { - return false; - } - } else if (!urlScheme.equals(other.urlScheme)) { - return false; - } - return true; - } - - @Override - public String toString() { - return "RemoteAppData [jmxurl=" + jmxurl + ", host=" + host + ", urlScheme=" + urlScheme + ", port=" + port - + ", keepChecking=" + keepChecking + ", processId=" + processId + ", processName=" + processName + "]"; + return Objects.equals(host, other.host) && Objects.equals(jmxurl, other.jmxurl) + && keepChecking == other.keepChecking && manualConnect == other.manualConnect + && Objects.equals(port, other.port) && Objects.equals(processId, other.processId) + && Objects.equals(processName, other.processName) && Objects.equals(urlScheme, other.urlScheme); } } diff --git a/eclipse-language-servers/org.springsource.ide.eclipse.commons.core/.classpath b/eclipse-language-servers/org.springsource.ide.eclipse.commons.core/.classpath index 43b986286..1db08c6b4 100644 --- a/eclipse-language-servers/org.springsource.ide.eclipse.commons.core/.classpath +++ b/eclipse-language-servers/org.springsource.ide.eclipse.commons.core/.classpath @@ -1,6 +1,6 @@ - + diff --git a/eclipse-language-servers/org.springsource.ide.eclipse.commons.core/.settings/org.eclipse.jdt.core.prefs b/eclipse-language-servers/org.springsource.ide.eclipse.commons.core/.settings/org.eclipse.jdt.core.prefs index 0f4fb64cb..85ccc6894 100644 --- a/eclipse-language-servers/org.springsource.ide.eclipse.commons.core/.settings/org.eclipse.jdt.core.prefs +++ b/eclipse-language-servers/org.springsource.ide.eclipse.commons.core/.settings/org.eclipse.jdt.core.prefs @@ -9,8 +9,8 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullable.secondary= org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.autoboxing=ignore @@ -21,6 +21,7 @@ org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled org.eclipse.jdt.core.compiler.problem.discouragedReference=warning org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore @@ -66,6 +67,7 @@ org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=igno org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled @@ -101,8 +103,8 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=1.8 +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 diff --git a/eclipse-language-servers/org.springsource.ide.eclipse.commons.core/META-INF/MANIFEST.MF b/eclipse-language-servers/org.springsource.ide.eclipse.commons.core/META-INF/MANIFEST.MF index d572518da..2b8b6bd33 100644 --- a/eclipse-language-servers/org.springsource.ide.eclipse.commons.core/META-INF/MANIFEST.MF +++ b/eclipse-language-servers/org.springsource.ide.eclipse.commons.core/META-INF/MANIFEST.MF @@ -21,7 +21,7 @@ Require-Bundle: org.eclipse.core.resources, org.eclipse.jface, org.apache.commons.lang3 Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-RequiredExecutionEnvironment: JavaSE-11 Export-Package: org.springsource.ide.eclipse.commons.core, org.springsource.ide.eclipse.commons.core.preferences, org.springsource.ide.eclipse.commons.core.process, @@ -36,3 +36,4 @@ Import-Package: org.eclipse.core.runtime, org.eclipse.osgi.util, org.osgi.framework, org.osgi.service.prefs +Automatic-Module-Name: org.springsource.ide.eclipse.commons.core diff --git a/eclipse-language-servers/org.springsource.ide.eclipse.commons.frameworks.test.util/.classpath b/eclipse-language-servers/org.springsource.ide.eclipse.commons.frameworks.test.util/.classpath index eca7bdba8..e801ebfb4 100644 --- a/eclipse-language-servers/org.springsource.ide.eclipse.commons.frameworks.test.util/.classpath +++ b/eclipse-language-servers/org.springsource.ide.eclipse.commons.frameworks.test.util/.classpath @@ -1,6 +1,6 @@ - + diff --git a/eclipse-language-servers/org.springsource.ide.eclipse.commons.frameworks.test.util/.settings/org.eclipse.jdt.core.prefs b/eclipse-language-servers/org.springsource.ide.eclipse.commons.frameworks.test.util/.settings/org.eclipse.jdt.core.prefs index 0c68a61dc..7adc0fb9a 100644 --- a/eclipse-language-servers/org.springsource.ide.eclipse.commons.frameworks.test.util/.settings/org.eclipse.jdt.core.prefs +++ b/eclipse-language-servers/org.springsource.ide.eclipse.commons.frameworks.test.util/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,10 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.8 +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/eclipse-language-servers/org.springsource.ide.eclipse.commons.frameworks.test.util/META-INF/MANIFEST.MF b/eclipse-language-servers/org.springsource.ide.eclipse.commons.frameworks.test.util/META-INF/MANIFEST.MF index 4c3bf3e07..b31639caa 100644 --- a/eclipse-language-servers/org.springsource.ide.eclipse.commons.frameworks.test.util/META-INF/MANIFEST.MF +++ b/eclipse-language-servers/org.springsource.ide.eclipse.commons.frameworks.test.util/META-INF/MANIFEST.MF @@ -5,7 +5,7 @@ Bundle-SymbolicName: org.springsource.ide.eclipse.commons.frameworks.test.util;s Bundle-Version: 4.15.2.qualifier Bundle-ActivationPolicy: lazy Bundle-Vendor: VMware, Inc. -Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-RequiredExecutionEnvironment: JavaSE-11 Require-Bundle: org.springsource.ide.eclipse.commons.tests.util, org.eclipse.debug.core, org.hamcrest.library, @@ -17,3 +17,4 @@ Require-Bundle: org.springsource.ide.eclipse.commons.tests.util, Export-Package: org.springsource.ide.eclipse.commons.frameworks.test.util Import-Package: org.apache.log4j;resolution:=optional, org.slf4j;resolution:=optional +Automatic-Module-Name: org.springsource.ide.eclipse.commons.frameworks.test.util diff --git a/eclipse-language-servers/org.springsource.ide.eclipse.commons.tests.util/.classpath b/eclipse-language-servers/org.springsource.ide.eclipse.commons.tests.util/.classpath index 626a83e9e..bc57d2383 100644 --- a/eclipse-language-servers/org.springsource.ide.eclipse.commons.tests.util/.classpath +++ b/eclipse-language-servers/org.springsource.ide.eclipse.commons.tests.util/.classpath @@ -1,8 +1,7 @@ - + - - + diff --git a/eclipse-language-servers/org.springsource.ide.eclipse.commons.tests.util/.settings/org.eclipse.jdt.core.prefs b/eclipse-language-servers/org.springsource.ide.eclipse.commons.tests.util/.settings/org.eclipse.jdt.core.prefs index f33e838f8..da265eab4 100644 --- a/eclipse-language-servers/org.springsource.ide.eclipse.commons.tests.util/.settings/org.eclipse.jdt.core.prefs +++ b/eclipse-language-servers/org.springsource.ide.eclipse.commons.tests.util/.settings/org.eclipse.jdt.core.prefs @@ -6,8 +6,8 @@ org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annota org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.autoboxing=ignore @@ -18,6 +18,7 @@ org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled org.eclipse.jdt.core.compiler.problem.discouragedReference=warning org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore @@ -61,6 +62,7 @@ org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=igno org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled @@ -92,8 +94,8 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 diff --git a/eclipse-language-servers/org.springsource.ide.eclipse.commons.tests.util/META-INF/MANIFEST.MF b/eclipse-language-servers/org.springsource.ide.eclipse.commons.tests.util/META-INF/MANIFEST.MF index 8ac5659c2..1a88edfec 100644 --- a/eclipse-language-servers/org.springsource.ide.eclipse.commons.tests.util/META-INF/MANIFEST.MF +++ b/eclipse-language-servers/org.springsource.ide.eclipse.commons.tests.util/META-INF/MANIFEST.MF @@ -14,8 +14,9 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.net, org.springsource.ide.eclipse.commons.core, org.springsource.ide.eclipse.commons.frameworks.core -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-RequiredExecutionEnvironment: JavaSE-11 Export-Package: org.springsource.ide.eclipse.commons.tests.util, org.springsource.ide.eclipse.commons.tests.util.swtbot Import-Package: org.apache.log4j;resolution:=optional, org.slf4j;resolution:=optional +Automatic-Module-Name: org.springsource.ide.eclipse.commons.tests.util diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java index d9c7250d8..08fd5e5a3 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java @@ -175,7 +175,7 @@ public final class SimpleLanguageServer implements Sts4LanguageServer, LanguageC @Override public void progressDone(String taskId) { STS4LanguageClient client = SimpleLanguageServer.this.client; - if (client != null && activeTaskIDs.remove(taskId)) { + if (client != null && activeTaskIDs.remove(taskId) != null) { ProgressParams progressParams = new ProgressParams(); progressParams.setToken(taskId); WorkDoneProgressEnd report = new WorkDoneProgressEnd(); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessCommandHandler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessCommandHandler.java index 65c06afd4..3c28fef5d 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessCommandHandler.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessCommandHandler.java @@ -100,7 +100,8 @@ public class SpringProcessCommandHandler { if (SpringProcessConnectorLocal.isAvailable()) { // Try cached processes. - SpringProcessDescriptor[] processes = localProcessConnector.getProcesses(false, SpringProcessStatus.REGULAR, SpringProcessStatus.AUTO_CONNECT); + SpringProcessDescriptor[] processes = localProcessConnector + .getProcesses(false, SpringProcessStatus.REGULAR, SpringProcessStatus.AUTO_CONNECT); for (SpringProcessDescriptor process : processes) { if (process.getProcessKey().equals(processKey)) { localProcessConnector.connectProcess(process); @@ -108,7 +109,8 @@ public class SpringProcessCommandHandler { } } - processes = localProcessConnector.getProcesses(true, SpringProcessStatus.REGULAR, SpringProcessStatus.AUTO_CONNECT); + processes = localProcessConnector + .getProcesses(true, SpringProcessStatus.REGULAR, SpringProcessStatus.AUTO_CONNECT); for (SpringProcessDescriptor process : processes) { if (process.getProcessKey().equals(processKey)) { localProcessConnector.connectProcess(process); diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessConnectorRemote.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessConnectorRemote.java index 05889e891..544560cea 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessConnectorRemote.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessConnectorRemote.java @@ -16,6 +16,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.Set; import org.slf4j.Logger; @@ -34,6 +35,7 @@ public class SpringProcessConnectorRemote { private String host; private String urlScheme = "https"; private String port = "443"; + private boolean manualConnect = false; private boolean keepChecking = true; //keepChecking defaults to true. Boot dash automatic remote apps should override this explicitly. //Reason. All other 'sources' of remote apps are 'manual' and we want them to default to @@ -97,28 +99,27 @@ public class SpringProcessConnectorRemote { public void setProcessName(String processName) { this.processName = processName; } - + @Override public String toString() { - return "RemoteBootAppData [jmxurl=" + jmxurl + ", host=" + host + ", urlScheme=" + urlScheme + ", port=" + port - + ", keepChecking=" + keepChecking + ", processId=" + processId + ", processName=" + processName + "]"; + return "RemoteBootAppData [jmxurl=" + jmxurl + ", host=" + host + ", urlScheme=" + urlScheme + ", port=" + + port + ", manualConnect=" + manualConnect + ", keepChecking=" + keepChecking + ", processId=" + + processId + ", processName=" + processName + "]"; + } + + public void setManualConnection(boolean manualConnect) { + this.manualConnect = manualConnect; + } + + public boolean isManualConnect() { + return manualConnect; } @Override public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((host == null) ? 0 : host.hashCode()); - result = prime * result + ((jmxurl == null) ? 0 : jmxurl.hashCode()); - result = prime * result + (keepChecking ? 1231 : 1237); - result = prime * result + ((port == null) ? 0 : port.hashCode()); - result = prime * result + ((processId == null) ? 0 : processId.hashCode()); - result = prime * result + ((urlScheme == null) ? 0 : urlScheme.hashCode()); - result = prime * result + ((processId == null) ? 0 : processId.hashCode()); - result = prime * result + ((processName == null) ? 0 : processName.hashCode()); - return result; + return Objects.hash(host, jmxurl, keepChecking, manualConnect, port, processId, processName, urlScheme); } - + @Override public boolean equals(Object obj) { if (this == obj) @@ -128,39 +129,10 @@ public class SpringProcessConnectorRemote { if (getClass() != obj.getClass()) return false; RemoteBootAppData other = (RemoteBootAppData) obj; - if (host == null) { - if (other.host != null) - return false; - } else if (!host.equals(other.host)) - return false; - if (jmxurl == null) { - if (other.jmxurl != null) - return false; - } else if (!jmxurl.equals(other.jmxurl)) - return false; - if (keepChecking != other.keepChecking) - return false; - if (port == null) { - if (other.port != null) - return false; - } else if (!port.equals(other.port)) - return false; - if (processId == null) { - if (other.processId != null) - return false; - } else if (!processId.equals(other.processId)) - return false; - if (processName == null) { - if (other.processName != null) - return false; - } else if (!processName.equals(other.processName)) - return false; - if (urlScheme == null) { - if (other.urlScheme != null) - return false; - } else if (!urlScheme.equals(other.urlScheme)) - return false; - return true; + return Objects.equals(host, other.host) && Objects.equals(jmxurl, other.jmxurl) + && keepChecking == other.keepChecking && manualConnect == other.manualConnect + && Objects.equals(port, other.port) && Objects.equals(processId, other.processId) + && Objects.equals(processName, other.processName) && Objects.equals(urlScheme, other.urlScheme); } } @@ -211,7 +183,9 @@ public class SpringProcessConnectorRemote { remoteAppInstances.computeIfAbsent(data, (_appData) -> { logger.info("Creating RemoteStringBootApp: " + _appData); String processKey = getProcessKey(_appData); - connectProcess(_appData); + if (!_appData.isManualConnect()) { + connectProcess(_appData); + } return processKey; }); } diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessTracker.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessTracker.java index 8fda9bd14..39d94d084 100644 --- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessTracker.java +++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/livehover/v2/SpringProcessTracker.java @@ -96,7 +96,8 @@ public class SpringProcessTracker { private void update() { try { - SpringProcessDescriptor[] autoConnectProcesses = this.localProcessConnector.getProcesses(true, SpringProcessStatus.AUTO_CONNECT); + SpringProcessDescriptor[] autoConnectProcesses = this.localProcessConnector + .getProcesses(true, SpringProcessStatus.AUTO_CONNECT); Set autoConnectProcessKeys = new HashSet<>();