diff --git a/src/com/atsebak/embeddedlinuxjvm/commandline/AppCommandLineState.java b/src/com/atsebak/embeddedlinuxjvm/commandline/AppCommandLineState.java index 746a35f..8e5138c 100644 --- a/src/com/atsebak/embeddedlinuxjvm/commandline/AppCommandLineState.java +++ b/src/com/atsebak/embeddedlinuxjvm/commandline/AppCommandLineState.java @@ -132,8 +132,11 @@ protected OSProcessHandler startProcess() throws ExecutionException { handler.addProcessListener(new ProcessAdapter() { private void closeSSHConnection() { try { + EmbeddedLinuxJVMConsoleView instance = EmbeddedLinuxJVMConsoleView.getInstance(project); + JavaStatusChecker javaStatusChecker = new JavaStatusChecker(instance); + javaStatusChecker.forceStopJavaApplication(instance.getSession(), configuration.getRunnerParameters().isRunAsRoot(), configuration.getRunnerParameters().getMainclass()); if (isDebugMode) { - //todo fix tcp connection closing issue random error message showing up + //todo fix tcp connection closing issue random error message showing up, its because remote debugger needs to be closed before embedded console final DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(project).getContext().getDebuggerSession(); if (debuggerSession == null) { return; @@ -206,7 +209,7 @@ public void onTextAvailable(ProcessEvent event, Key outputType) { @Override protected JavaParameters createJavaParameters() throws ExecutionException { EmbeddedLinuxJVMConsoleView.getInstance(project).clear(); - JavaParameters javaParams = new JavaParameters(); + final JavaParameters javaParams = new JavaParameters(); final ProjectRootManager manager = ProjectRootManager.getInstance(project); javaParams.setJdk(manager.getProjectSdk()); @@ -248,7 +251,8 @@ public void run() { } catch (Exception e) { EmbeddedLinuxJVMConsoleView.getInstance(project).print(EmbeddedLinuxJVMBundle.message("pi.connection.failed", e.getMessage()) + "\r\n", ConsoleViewContentType.ERROR_OUTPUT); - //todo should cancel application + JavaStatusChecker javaStatusChecker = new JavaStatusChecker(null, EmbeddedLinuxJVMConsoleView.getInstance(project)); + javaStatusChecker.stopApplication(-1); } } }); @@ -260,7 +264,7 @@ public void run() { @Override public void run(@NotNull ProgressIndicator progressIndicator) { if (isDebugMode) { - progressIndicator.setIndeterminate(true); +// progressIndicator(true); final String initializeMsg = String.format(DEBUG_TCP_MESSAGE, configuration.getRunnerParameters().getPort()); //this should wait until the deployment states that it's listening to the port while (!outputForwarder.toString().contains(initializeMsg)) { @@ -359,7 +363,6 @@ public Boolean fun(String title) { content.getManager().setSelectedContent(content); ToolWindow window = ToolWindowManager.getInstance(project).getToolWindow(executor.getToolWindowId()); window.activate(null, false, true); - return; } } } diff --git a/src/com/atsebak/embeddedlinuxjvm/commandline/JavaStatusChecker.java b/src/com/atsebak/embeddedlinuxjvm/commandline/JavaStatusChecker.java index eca7f42..6b08b62 100644 --- a/src/com/atsebak/embeddedlinuxjvm/commandline/JavaStatusChecker.java +++ b/src/com/atsebak/embeddedlinuxjvm/commandline/JavaStatusChecker.java @@ -11,10 +11,17 @@ import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.openapi.project.Project; +import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelExec; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.Session; import lombok.SneakyThrows; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; import java.util.Collection; import java.util.List; @@ -23,6 +30,11 @@ public class JavaStatusChecker extends Thread { private final Project project; private final EmbeddedLinuxJVMConsoleView consoleView; + public JavaStatusChecker(@NotNull EmbeddedLinuxJVMConsoleView consoleView) { + this.consoleView = consoleView; + project = null; + channelExec = null; + } public JavaStatusChecker(@NotNull ChannelExec channelExec, @NotNull EmbeddedLinuxJVMConsoleView consoleView) { this.channelExec = channelExec; this.project = consoleView.getProject(); @@ -44,11 +56,40 @@ public void run() { } /** - * Stops the applications via the descriptor of configuration + * Stops java application that needs to, this should be called when the user wants to manually stop the application + * so that it kills the remote java process + * + * @param session + * @param isRunningAsRoot + * @param mainClass + * @throws JSchException + * @throws IOException + */ + public void forceStopJavaApplication(@Nullable Session session, @NotNull boolean isRunningAsRoot, @NotNull String mainClass) throws JSchException, IOException { + if (session == null) { + return; + } + String javaKillCmd = String.format("%s kill -9 $(ps -efww | grep \"%s\"| grep -v grep | tr -s \" \"| cut -d\" \" -f2)", + isRunningAsRoot ? "sudo" : "", mainClass); + Channel channel = session.openChannel("shell"); + + OutputStream inputstream_for_the_channel = channel.getOutputStream(); + PrintStream commander = new PrintStream(inputstream_for_the_channel, true); + + channel.connect(); + + commander.println(javaKillCmd); + commander.close(); + channel.disconnect(); + session.disconnect(); + } + + /** + * Stops the applications via the descriptor of configuration. This gets called when the application finishes on the client side without maniually closing it. * * @param javaExitCode */ - private void stopApplication(@NotNull int javaExitCode) { + public void stopApplication(@NotNull int javaExitCode) { final RunManagerImpl runManager = (RunManagerImpl) RunManager.getInstance(project); final Collection allConfigurations = runManager.getSortedConfigurations(); List allDescriptors = ExecutionManager.getInstance(project).getContentManager().getAllDescriptors(); diff --git a/src/com/atsebak/embeddedlinuxjvm/protocol/ssh/SSHHandlerTarget.java b/src/com/atsebak/embeddedlinuxjvm/protocol/ssh/SSHHandlerTarget.java index 453b3ec..69614ec 100644 --- a/src/com/atsebak/embeddedlinuxjvm/protocol/ssh/SSHHandlerTarget.java +++ b/src/com/atsebak/embeddedlinuxjvm/protocol/ssh/SSHHandlerTarget.java @@ -114,6 +114,7 @@ private void forceCreateDirectories(@NotNull final String path) throws IOExcepti private void runJavaApp(@NotNull final String path, @NotNull final String cmd) throws IOException, RuntimeConfigurationException { consoleView.print(NEW_LINE + EmbeddedLinuxJVMBundle.getString("pi.deployment.build") + NEW_LINE + NEW_LINE, ConsoleViewContentType.SYSTEM_OUTPUT); Session session = connect(ssh.get()); + consoleView.setSession(session); try { ChannelExec channelExec = (ChannelExec) session.openChannel("exec"); channelExec.setOutputStream(System.out, true);