java.lang.InterruptedException while running a batch file - java

I am trying to run a batch file which has set of services I want to restart. When I call this batch file from my Java application I get Interrupted Exception.
My batch file
call net stop app-service
call net start app-service
call net stop ui-service
call net start ui-service
call net stop custom-app
call net start custom-app
call net stop MSSQLSERVER /Y
call net start MSSQLSERVER
My java code to run the batch file
File file = new File(System.getProperty("user.dir") + File.separator + "restart.bat");
String time="cmd /c "+file.getAbsolutePath();
Process p = Runtime.getRuntime().exec(command);
int exitvalue = p.waitFor();
I'm getting the following error
java.lang.InterruptedException
at java.lang.ProcessImpl.waitFor(ProcessImpl.java:451)
What am I doing wrong?

Looks like the problem is with the batch file. Calling stop and start immediately is what's causing the issue. Make sure the SQL server and services are stopped, then start the server and those services.
Please check this answer:
Stop and Start a service via batch or cmd file
Use the SC (service control) command, it gives you a lot more options
than just start & stop.
DESCRIPTION:
SC is a command line program used for communicating with the
NT Service Controller and services. USAGE:
sc [command] [service name] ...
The option <server> has the form "\\ServerName"
Further help on commands can be obtained by typing: "sc [command]"

Related

Restart Tomcat with Java

I need to restart the tomcat from Java code.
For eg, if a query is not executed for a certain time Period then it will restart the tomcat automatically.
I have tried the following shutdown and startup code, but when we shutdown the tomcat then the java code will not run and tomcat not started.
Note :- I am running this code from a application and restarting the same tomact which the same application is using.
Following the code
try {
PreparedStatement.setQueryTimeout(10);
rs = PreparedStatement.executeQuery();
} catch (SQLException ex) {
System.out.println("IN CATCH BLOCK FOR THE REFRESH INVOICE");
String shutcommand = "killall java";
Process shutchild = Runtime.getRuntime().exec(shutcommand);
System.out.println("JAVA PROCESS KILLED");
String locationCommand = "cd /root/cluster/tomcat6/bin";
Process locationChild = Runtime.getRuntime().exec(locationCommand);
String strtcommand = "./startup.sh";
Process strtchild = Runtime.getRuntime().exec(strtcommand);
}
Killing tomcat after SQLException this is not good idea to handle this exception. Probably the problem is on database site.
But if you are sure, that it is what you need you can kill this java proces in this section, but to run tomcat you should use for example bash and cron. Why? Beacues after killing your executing code will stop, so you don't achieve the line to start tomcat.
How to check tomcat: Is Tomcat running?
TL;DR
File binaryDir = new File(System.getProperty("catalina.home") + File.separator + "bin");
String restartCommand = "\"shutdown.bat & ping 0.0.0.0 -n 4 & C:\\WINDOWS\\system32\\net start Tomcat8\"";
new ProcessBuilder("cmd", "/c", restartCommand).directory(binaryDir).start();
Survive
Creating new process will survive JVM shutdown. If you combine commands in one line
it should work fine according to my tests and this.
shutdown.bat
You need to use shutdown.bat instead stopping windows service because it often fails on Windows with message Cannot stop service Apache Tomcat...
ping 0.0.0.0 -n 4
You need to wait some time after shutdown otherwise you will get Service is already starting. Try again later error message. Also note I use ping instead timeout because it causes problems on some systems.
C:\WINDOWS\system32\net start Tomcat8
I'm starting windows service because invoking startup.bat won't work for me. Also remember to replace Tomcat8 if you using different tomcat or custom service name for example Tomcat7
Redirect I/O
Don't redirect input or output of process instance or command will shutdown with JVM, and Tomcat won't start.
You can execute this native command using java
String command = "c:\program files\tomcat\bin\startup.bat";//for linux use .sh
Process child = Runtime.getRuntime().exec(command);
You should consider using ProcessBuilder instead of Runtime exec. Also, you should split all the arguments when you want to execute a command.
I suggest this :
ProcessBuilder shutcommand = new ProcessBuilder("killall", "java");
Process shutchild = shutcommand.start();
System.out.println("JAVA PROCESS KILLED");
ProcessBuilder strtcommand = new ProcessBuilder("/root/cluster/tomcat6/bin/startup.sh", "java");
Process strtchild = strtcommand.start();

How to Terminate a Process Normally Created using ProcessBuilder

I am creating Processes using ProcessBuilder in my Java Application. The created process executes some FFMPEG commands which actually copy the RTSP streams in specified destination media file.
ProcessBuilder builder = new ProcessBuilder("ffmpeg", "-i", RTSP_URL, "-f", fileFormat, destFilePath);
Process processToExecute = builder.start();
I want to close the process before it completes its execution. So, If I run this FFMPEG command directly in windows CMD and then press 'CTRL+C' after 5 seconds then process get terminates with status '2'. And I can play the media file created so far.
So, If I do the same operation in my Java Application using:
process.destroy(); //I call this method after 5 sec
I get the status code '1' which means abnormal termination. I get the status by the following way:
processToExecute.destroy();
processToExecute.exitValue(); //This return me status '1'
And I can't play the media file and I think this is due to the abnormal termination of the process.
So how I can terminate the process created using ProcessBuilder in the same way we do in CMD with (CTRL+C) so that I may play the created media file ?
I want to terminate process (created using ProcessBuilder) in Java Application with status code of '2' that I get when I terminate process using CMD.
EDIT#01: --- Sharing Findings
So, when I try to delete that file once app terminates, I get the following error:
The Action Can't be Performed Because File is Opened in FFMPEG.exe
Which means that process is not terminating the command it is executing. That command still has occupied this file that's why I am not getting able to play it. Process gets terminate when I call:
processToExecute.destroy();
But, the task it is performing (that is execution of a command) is still active. Strange!!!!
EDIT#02: Sharing Ultimate Reason
Actually If I directly press 'CTRL+C' or 'q' in cmd when process is running then it terminates the process successfully and this process is no more visible in the currently executing processes lists.
And Programatically when I call method:
cmd> processToExecute.destroy();
It terminates the process but when I see the list of currently executing processes I can still see them over there.
And same scenario exists If I try to terminate this process using 'taskkill' or 'kill' command in another CMD by specifying their's name or pid that still process terminates abnormally.
P.S. I use the following command to see the running processes:
tasklist
So from this it proves that destroy() method from Application and 'taskkill or kill' command from another CMD is not terminating the process normally that pressing 'CTRL+C' and 'q' does.
Maybe try...
builder.inheritIO();
System.exit(2);
Or you could try to write to the stdin of the process...
process.getInputStream().write(exitCode);

ActiveMQ query: How to start

I am starting ActiveMQ process through Java code like this:
ProcessBuilder pb = new ProcessBuilder(activeMQHome + "run_activemq.sh",
logDirectory,
activeMQHome,
brokerPath);
pb.start();
logDirectory: log location
activeMQHome: /Common/thirdParty/apache-activemq-5.3.0/bin/
brokerPath: brokerPath location
Now I have to start this process thorugh command line. Or to be more specific, I have to start it through /etc/inittab so that it can start automatically.
What entry should I give? I can start it by ./run_activemq.sh but how will I give logDirectory and brokerPath?
Actually there is need to start AMQ process through Java code. ActiveMQ already comes with start/stop script in its $ACTIVEMQ_HOME/bin directory and that you can very well put in /etc/inittab to start at system startup. Log Directory and other settings are configured in $ACTIVEMQ_HOME/conf/activemq.xml file.

how to restart tomcat from a running webapp?

I need to restart tomcat service from a webapp running on this tomcat. So I'm trying to execute script that stops tomcat service, and then starts it:
echo "before stop" >> textfile.txt
NET STOP "Tomcat7"
:loop
timeout 3
SC query Tomcat7 | FIND "STATE" | FIND "RUNNING" > NUL
IF ERRORLEVEL 1 (
goto start
) ELSE (
goto loop
)
:start
NET START "Tomcat7"
Java code:
String command = "C:\\Tomcat 7.0\\bin\\restart.bat";
Process p = Runtime.getRuntime().exec(command);
Tomcat is stopped, but not started.
If I run this batch from command line, it works properly.
thank you for your time
This worked:
String fileName = "C:\\Tomcat 7.0\\bin\\restart.bat";
String[] commands = {"cmd", "/c", "start", "\"DummyTitle\"",fileName};
Runtime.getRuntime().exec(commands);
taken from http://www.rgagnon.com/javadetails/java-0014.html
What you are asking is not exactly safe and possible but do take a look at Tomcat manager API that allows you to programmatically manipulate Tomcat deployment and instance:
http://tomcat.apache.org/tomcat-7.0-doc/api/index.html
http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/manager/host/HostManagerServlet.html
Agree with Edmon.
Tomcat is a provider of containers. Each container should act independently of each other, even if they call the services another provides. This should all be done via RMI or alike.
Like Edmon also suggests, you could call using the API, but again... sounds bad. Instead, question why it needs to restart. Then, if there's no work around, use the Tomcat Manager.

Monitoring a batch file with java

I'm calling a batch that calls another "jar" that send messages to a server and write a report in the end, the time of execution varies from day to day, and the size of the input used in the batch influences to.
I would like to monitor when the batch auto-closes so I can make my original jar to read the log...
I'm calling it like this
Process prog = Runtime.getRuntime().exec("cmd /c start C:\\chamados\\corretorRota\\VerificarNumero.bat");
and the batch:
cd C:\chamados\corretorRota
java -jar BatchDispatcher.jar brux0043 5873 gcpn-rota.txt > resultado.txt
exit
(FYI brux0043 = server, 5873 = port gcpn-rota = input file writed previously)
(the batch keeps open util the end of the called jar)
You can write a log with the timestamp whenever the batch file was executed.
put this line in your batch file
echo. |time |find "current" >> log
this will then write the timestamp when the batch file was run to the log. Also, there should be a file called log before executing the batch file.
Now your java program can monitor the log and know how many times and when the batch file was executed.
You should use
prog.waitFor()
to wait for the process to finish execution.

Categories