public void doUndeploy( ContextImpl undeployingContext, Handler<AsyncResult<Void>> completionHandler) { if (!children.isEmpty()) { final int size = children.size(); AtomicInteger childCount = new AtomicInteger(); for (Deployment childDeployment : new HashSet<>(children)) { childDeployment.doUndeploy( undeployingContext, ar -> { children.remove(childDeployment); if (ar.failed()) { reportFailure(ar.cause(), undeployingContext, completionHandler); } else if (childCount.incrementAndGet() == size) { // All children undeployed doUndeploy(undeployingContext, completionHandler); } }); } } else { undeployed = true; context.runOnContext( v -> { Future<Void> stopFuture = new FutureResultImpl<>(); stopFuture.setHandler( ar -> { deployments.remove(id); context.runCloseHooks( ar2 -> { if (ar2.failed()) { // Log error but we report success anyway log.error("Failed to run close hook", ar2.cause()); } if (ar.succeeded()) { reportSuccess(null, undeployingContext, completionHandler); } else { reportFailure(ar.cause(), undeployingContext, completionHandler); } }); }); try { verticle.stop(stopFuture); } catch (Throwable t) { stopFuture.setFailure(t); } }); } }