void () { boolean keepRunning = myKeepRunning; try { final JavacRemoteProto.Message result = compile(context, sessionId, options, files, cp, platformCp, modulePath, upgradeModulePath, srcPath, outs, new CanceledStatus() { @Override public boolean isCanceled() { return Boolean.TRUE.equals(myCanceled.get(sessionId)); } }); context.channel().writeAndFlush(result).awaitUninterruptibly(); } catch (Throwable throwable) { // in case of unexpected exception exit, to ensure the process is not stuck in a problematic state keepRunning = false; throwable.printStackTrace(System.err); try { // attempt to report via proto context.channel().writeAndFlush(JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createFailure(throwable.getMessage(), throwable))); } catch (Throwable ignored) { } } finally { myCanceled.remove(sessionId); // state cleanup if (keepRunning) { JavacMain.clearCompilerZipFileCache(); //noinspection CallToSystemGC System.gc(); } else { // in this mode this is only one-time compilation process that should stop after build is complete ExternalJavacProcess.this.stop(); } Thread.interrupted(); // reset interrupted status } }