diff --git a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootApp.java b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootApp.java index 05de1ffce..adcc0dbf7 100644 --- a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootApp.java +++ b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootApp.java @@ -41,6 +41,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableList; +import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.VirtualMachineDescriptor; @@ -85,7 +86,7 @@ public class SpringBootApp { return getAllRunningJavaApps().stream().filter(SpringBootApp::isSpringBootApp).collect(CollectorUtil.toImmutableList()); } - public SpringBootApp(VirtualMachineDescriptor vmd) throws Exception { + public SpringBootApp(VirtualMachineDescriptor vmd) throws AttachNotSupportedException, IOException { this.vmd = vmd; this.vm = VirtualMachine.attach(vmd); Log.info("SpringBootApp created: "+this); @@ -113,7 +114,9 @@ public class SpringBootApp { isSpringBootAppSysprops() ); } catch (Exception e) { - Log.log(e); + //Couldn't determine if the VM is a spring boot app. Could be it already died. Or could be its not accessible (yet). + // We will ignore the exception, pretend its not a boot app (most likely isn't) but DO NOT CACHE this result + // so it will be retried again on the next polling loop. return false; } } @@ -133,14 +136,9 @@ public class SpringBootApp { } - public boolean containsSystemProperty(Object key) { - try { - Properties props = this.vm.getSystemProperties(); - return props.containsKey(key); - } - catch (Exception e) { - return false; - } + public boolean containsSystemProperty(Object key) throws IOException { + Properties props = this.vm.getSystemProperties(); + return props.containsKey(key); } public String getPort() throws Exception { diff --git a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootAppCache.java b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootAppCache.java index 618d5d712..b5506bce1 100644 --- a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootAppCache.java +++ b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootAppCache.java @@ -15,8 +15,6 @@ import java.util.Collection; import java.util.HashSet; import java.util.List; -import org.springframework.ide.vscode.commons.util.Log; - import com.google.common.collect.ImmutableMap; import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.VirtualMachineDescriptor; @@ -37,25 +35,27 @@ public class SpringBootAppCache { private void refresh() { List currentVms = VirtualMachine.list(); - HashSet oldVms = new HashSet<>(apps.keySet()); - ImmutableMap.Builder newApps = ImmutableMap.builder(); + ImmutableMap.Builder newAppsBuilder = ImmutableMap.builder(); for (VirtualMachineDescriptor vm : currentVms) { - oldVms.remove(vm); SpringBootApp existingApp = apps.get(vm); if (existingApp!=null) { - newApps.put(vm, existingApp); + newAppsBuilder.put(vm, existingApp); } else { try { - newApps.put(vm, new SpringBootApp(vm)); + newAppsBuilder.put(vm, new SpringBootApp(vm)); } catch (Exception e) { - Log.log(e); + //Ignore problems attaching to a VM. We will try again on next polling loop, if vm still exists. + //The most likely cause is that the VM already died since we obtained a reference to it. } } } + HashSet oldVms = new HashSet<>(apps.keySet()); + ImmutableMap newApps = newAppsBuilder.build(); + oldVms.removeAll(newApps.keySet()); for (VirtualMachineDescriptor oldVm : oldVms) { apps.get(oldVm).dispose(); } - apps = newApps.build(); + apps = newApps; nextRefreshAfter = System.currentTimeMillis() + EXPIRE_AFTER.toMillis(); } }