How to remotely kill a process on amazon EC2 linux instance - java

I use Amazon EC2 instances to perform some complex computation by using the AWS Java SDK, these computations might take so long sometimes. Hence, I need to kill the process running on the EC2 instance remotely from my Java code so that I can reuse the same instance for another task without needing to stop and start the instance.
The problem with stop and start, is that Amazon treat partial hours as complete hours, so my aim is to make my code more cost effective.
I use SSH to connect with my EC2 instances and that is how I pass commands to be executed there. I doubt that if I disconnect the SSH connection and connect to it again, it would kill whatever process was running there.
In short, what I need is away of doing Ctrl+C but from within my Java code (without user intervention). Is that possible?
EDIT:
To clarify, the computation is executed by a separate tool installed on the Linux EC2 instance. So I just pass the command to start this tool, then the command line waits until its finished and shows the results. On manual usage scenario, I can click Ctrl+C on linux command line and will get control of the command line back. But in my case, I want to do similar thing from java code if possible.

Use the SIGAR library to scan the process list on a machine and kill your process.
Use getProcList() to get all process IDs, getProcArgs() to get the full command line of each process, and kill() to kill the relevant process or processes.
So if a task is running and you want to kill it, SSH again into the machine and run your SIGAR based process killer.

One dirty/functional way would be to kill your process via SSH using the java Runtime to execute it.
Something like
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec("ssh user#host command");
So in your case, if you know the program's PID (1234 for example):
Process p = runtime.exec("ssh user#host kill 1234");
Or if you know the program's name:
Process p = runtime.exec("ssh user#host pkill my_program_name_x64");
Note that you usually have to give absolute paths to the executables invoked via runtime.
So you'll have to replace ssh by something like /bin/ssh or /usr/bin/ssh as well as for kill and pkill or killall.

Related

Writing bash script for restarting JVMs

I have an application which is deployed on Linux environment and has two JVM's simultaneously running. One is producer and one is consumer.
I have different targets written in my ant script for stopping and starting the two JVMs.
There are times while restarting the producer or the consumer, one of the JVMs fail to stop so we have to go and manually find the process id for that particular port and kill that process and then start the application.
How could I automate this and write one script for everything. This script should be able to call the ant targets for stopping the JVMs, kill the process if any JVMs does not stop and finally start the two JVMs.
The first and the last is fine. But how to write things like finding the process id against the port and then doing kill -9.
I am a Java developer so don't know much about this.
If your JVMs are communicating on a socket then try something like
lsof | grep ":$port " | awk '{print $2}'
where $port is the port number. This searches the list of open file descriptors for any matching the required port number and spits out the process id.

Java Runtime.exec communictation possible?

I have a main java program which should launch other java programs in an own process using Runtime.exec(), e.g.
Runtime.exec("java -jar myapp.jar");
Is there a possibility to communicate with this new process, e.g. sending request, chaing fields...?
How can I shutdown this new created process? I think I get an handler back and thus can kill the process. But is there a nicer way?
If I kill the process, will the shutdownhook still be executed before the process is killed?
Runtime.getRuntime().addShutdownHook
Is there a possibility to communicate with this new process, e.g. sending request, chaing fields...?
You can communicate with the process through the Process object returned by Runtime.exec. Just use Process.getInputStream/.getOutputStream.
If you want to invoke methods on the other Java process you could look into RMI ("Remote method invocation"). Another option is of course sockets. See this related answer.
There's no straight forward platform independent way of changing fields of the other Java process.
If I kill the process, will the shutdownhook still be executed before the process is killed?
Depends on how you kill it, but typically, yes, the shutdown hooks will be executed.

Operating terminal session from Java

I am trying to make a terminal emulator in Java. The java program will accept the commands from user, and show its output to them. I can emulate simple commands like 'ls', but I don't know how to handle commands like 'cd'. This is because, I am using exec() method for executing terminal commands. So, all the commands are executed at current directory. The commands like 'cd ..' are executed, but then they have no persistent effect, because each command is separately executed by exec().
Any Ideas How I can emulate a whole session??
If you are executing commands with exec(), you are not writing a terminal emulator; you are writing a shell. In that case, you will need to keep track of things the shell keeps track of, like environment variables and working directory.
If you really want to write a terminal emulator, you would be talking to a shell process through a pseudo-terminal. Then your program would just be keeping track of the things a terminal keeps track of, like the line state and what appears on the screen.
Working with a pseudo-terminal from Java will be a little tricky, because most of the documentation assumes you are using a C api. man pty should get you started. Your Java process will have to open the master side of the pseudo-terminal with FileStream objects. I'm not sure there is a way within Java to get a child process to open the slave side of the pseudo-terminal; you might have to invoke a shell command with exec() that starts another shell command with standard input/output/error redirected to the slave side of the pseudo terminal.
JSch is a pure Java implementation of SSH2.
JSch allows you to connect to an sshd server and use port forwarding, X11 forwarding, file transfer, etc., and you can integrate its functionality into your own Java programs.
http://www.jcraft.com/jsch/
You should really give a try to Ganymed.
Ganymed SSH-2 for Java is a library which implements the SSH-2
protocol in pure Java (tested on J2SE 1.4.2 and 5.0). It allows one to
connect to SSH servers from within Java programs. It supports SSH
sessions (remote command execution and shell access), local and remote
port forwarding, local stream forwarding, X11 forwarding, SCP and
SFTP.
http://www.ganymed.ethz.ch/ssh2/
Ganymed along with apache FTP client you can also download and upload files.
Also there is a inbuilt example code for terminal emulation in Ganymed.
The following is a link to a project which is did using Ganymed along with apache FTP client.
GITHUB
Happy Coding!!

how to stop a program running in the server?

I m doing a eclipse plugin project to create an IDE for a particular language.
For running i connect to the server and ask the user the command,type of connection...
After the program has started execution The only way to stop the execution of the program is by pressing "ctrl+C" when done in the command prompt.
I run the program by sending the server the following command:
"probevue filename.e >output.txt"
when i give this command it is running,but i m not able to stop the program...
i.e when i press Ctrl+C the program should stop execution.
How shall i do this?
Thanks in Advance.
after reading into this article about probevue it seems that you have started a dynamic session. i think the program you're calling is never terminating itself.
http://pic.dhe.ibm.com/infocenter/aix/v7r1/index.jsp?topic=%2Fcom.ibm.aix.cmds%2Fdoc%2Faixcmds4%2Fprobevue.htm
you should first read how to invoke a command properly. e.g. -> http://www.javalobby.org/java/forums/t53333.html
then you should think about how would you terminate the command if you wouldn't have the ctrl+c option, like finding out the process-id of the shell command you executed before (e.g.: ps -ef | grep ) and terminating it by using another shell command (e.g.: kill -9 )
hope this helps you find a solution.
Common eclipse server plugins like JBoss Tools call the server scripts that are delivered with the server for starting and stopping. Deployment/undeployment and starting/stopping of applications is done via the management port.
So either you have a manageable server to control your program, or you could work around the problem by writing the scripts yourself.

How to fire Java method using bash

Suppose I launch a Java application:
java -cp whatever.jar com.example.Start
Process launches ok and keeps running with PID 1314.
Now I would like the system to fire a method by users request.
How can I use bash to signal the running PID and have it fire a method?
My thought is to have bash echo data to the Java processes via a named pipe, which I'm pretty sure Java has support for.
To communicate with a Java process, you would normally use RMI from another process (this could be in the same JAR)
However, if you want a pure bash/unix utilities solution, you could have the application listen on a port for commands and send back responses. This means you could use plain telnet to send commands and get output. One example of this is to use a http server with wget or you could have a simple socket based solution.

Categories