Restart tomcat automatically when it gets outofmemory error - java

How can I configure Tomcat to automatically restart when get an out of memory [OOME] error.
As i think
-XX:OnOutOfMemoryError="/yourscripts/tomcat-restart"
But not sure here "yourscripts" stand for what directory?

The value you provide to -XX:OnOutOfMemoryError must be the fully qualified path to an executable (can be executable script). That script must return basically immediately so that the jvm can continue and shutdown. So it needs to attempt to stop and start tomcat in the background. This may result in effectively 2 scripts:
Script 1:
#!/bin/bash
script2.sh &
Script 2:
# stop tomcat
# make sure it is dead (kill "zombie" process if necessary)
# start tomcat
The -XX:OnOutOfMemoryError shoudl point to script 1.

Related

Java - how to use forever tool for the jar file?

On CentOS 7 i have /home/www/html/java-server/Objects/server.jar file which time to time crash for good reason and need to re-start again automatic so that its always running.
How to use forever like tool or any other similar for Java on CentOS?
For example on my NodeJS server i use as below.
forever start --minUptime 1000 --spinSleepTime 1000 SERVER.js
or
forever -m5 server.js
EDIT:
Reference: https://stackoverflow.com/a/28704296/285594
Wrap your jar in a shell script (this is optional but often useful) and use Supervisor to monitor it. Supervisor is highly customizable so you can set how many times your process can be restarted in a period of time, etc.
Here is how I did it.
I was trying to get a spring boot executable jar to run.
I created a bash script like the following
#!/bin/bash
forever start -c bash ./my-app.jar
The key here is to use "-c bash" otherwise forever failed to run the jar. Forever kept trying to run with node
You can write a class in Java that loops. It would call your application and catch exceptions, restarting the application after each exception. Make sure the wrapper class releases references to the application so that it can be GC'ed.

Start Tomcat on Console from Jenkins

I have a batch file which start Tomcat as follows (when running it on Windows it works fine)
...
start C:\Users\root\tomcat\tomcat2\bin\startup.bat
The batch file is called from Jenkins as follows
I have this error in the Jenkins Consol at the end of the build
D:\jenkins\workspace\Start 3T2>start C:\Users\root\tomcat\tomcat2\bin\startup.bat
Process leaked file descriptors. See http://wiki.jenkins-ci.org/display/JENKINS/Spawning+processes+from+build for more information
Finished: SUCCESS
When I check the task manager I see that the server is started but in background. I need actually to start Tomcat it in the Console.
This is what I did :
I added -Dhudson.util.ProcessTree.disable=true in jenkins-slave.xml
used to start jenkins slave service.
I added set BUILD_ID=dontkillme in startup.bat to stop Jenkins from
stopping the process in the end.
I think Tomcat start correctly in the end but not in Console. I'm running Windows 2012 server/Tomcat7/Jenkins 1.578.
Any idea on how to start Tomcat in a Console ?
AFAIK, if you're trying to start Tomcat console on a given machine which has Jenkins configured as service, it will not work. To make it work, you will have to connect to the given machine using JNLP. In case it's a standalone system and you want to open a Tomcat console using Jenkins, you will have to set up a Slave on the same machine and that too using JNLP (Launch slave agents via Java Web Start) in the Launch method section in Jenkins > Manage Jenkins > Manage Nodes > Slave Node's Configure page.
You can connect to the slave using any of the methods shown below. You will see the below option as soon as you configure the slave node and click Save. I ran the highlighted command from the Win command prompt. In my set up, i had configured Master and Slave on the same machine. I have Win 7 Professional, 64-bit laptop.
Once you run the command, you will see a small window that will pop-up and will display 'Connected' message as shown below:
At least for me, i checked that hudson.util.ProcessTree.disable=true & BUILD_ID parameters were not required. The only thing that i needed was to make sure that the following property is unset: HUDSON_SERVER_COOKIE
P.S.: You might have to make sure to start JNLP on reboot. A start-up script will do that. Also, ensure that your project/job is tied to the given slave which is running using JNLP mechanism.
i was going crazy with this , as shutdown.sh worked from Window-Master-Jenkin-->Linux-Slave-Jenkins, but startup.sh was not happening on my linux-slave-jenkins though startup.sh execution showed success message, as there were no logs anywhere, it was difficult to troubleshoot, not sure how and why setting up "export HUDSON_SERVER_COOKIE= " just before running startup.sh worked. Anyway Thanks a lot.

Checking if java code is running and attempt to restart if not (unix)

I have some java code that is running continuously on a raspberry pi (from the terminal) and listening to a twitter stream and saving data to disk/usb.
I would like to know what would be the preferred method of detecting if a program is still running so I can take appropriate action and attempt to restart the app?
I hope that in this manner I could detect the program has failed, send an email to notify me and attempt to rerun the code. Would running this in a server environment be the best way to go?
Have a look at the forever project. If you have npm installed you can use that to install the forever package with the -g (for global install) parameter:
npm install forever -g
Then use the start argument to start the script. In your case this could be a bash file (.sh) with the required java commands.
forever start name-of-script-here
If the script would fail (system.exit in java or any fatal error) it will be restarted by forever. You can also get a list of all the running scripts managed by forever with:
forever list
In Unix let a parent process create the child java process and have it monitor. If it terminates then the parent can restart it.
The Unix fork returns the child pid to the parent.
Using this technique: Tracking the death of a child process parent can monitor child's death.

Wait till tomcat startup is over

I am executing startup.bat programatically to start a tomcat server.
ProcessBuilder processUnzip = new ProcessBuilder("cmd", "/c", "start", "C:\\apache-tomcat-6.0.37\\startup.bat");
I need to wait till the complete startup.bat process is over. But the program ends immediately after the startup.bat is started.
Is there a way to wait till startup process is over
Update:
My requirement is to deploy a WAR file in a tomcat instance. I cannot use hot deployment or dynamic deployment. I have to do a static deployment. Basically the task is to automate the manual process of build deployment in tomcat.
You are facing this problem because startup.bat opens up a new window with Tomcat console and returns immediately.
Even if you use catalina.bat instead of startup.bat, that would still not work as that process would terminate only when Tomcat stops.
Technically, You would never know whether the tomcat is started on or until the logs tell you so. So the approach you are taking might not work.
The only crude solution I can think of is (with the same code you have), once you start the Tomcat, keep checking the console log file, at intervals, for specific string (like Server started etc) which indicate that the server has started.
BTW, if you could tell us your specific use case (why are you doing this ?), community here might come up with better alternatives.
To automate the process, you should copy the app to be deployed into tomcat deployments folder before you start the server up. If you copy any .war package to TOMCAT/webapps folder, it will get deployed by Tomcat when it starts up.
So what you need to do is to just copy the file. here are four different examples on how to do that in Java. Either that, or you can just exec a copy command.
Possibly easiest and least error prone is to do it using Files, in java 7:
Files.copy(source.toPath(), dest.toPath());
and after that is finished, then exec start command.
Update: with shutdown, you have the wait issue. You can wait doing something like this in a batch file:
CALL shutdown.bat
:LOOP
tasklist /FI "WINDOWTITLE eq Tomcat" | find /C /I ".exe" > NUL
IF ERRORLEVEL 1 (
GOTO :EOF
) ELSE (
ECHO Tomcat is still running
SLEEP 1
GOTO LOOP
)
This code assumes a Tomcat window with name 'Tomcat'. If you run Tomcat as a service, for example, that assumption is not true. For service however there are more reliable means using sc query:
SC stop "tomcat"
:LOOP
SC query "tomcat" | FIND "STATE" | FIND "RUNNING" > NUL
IF ERRORLEVEL 1 (
GOTO :EOF
) ELSE (
ECHO Tomcat is still running
SLEEP 1
GOTO LOOP
)
Here assuming service name "tomcat".
Update2: forgot we're talking about java here - with the bat above, you can use java .waitFor(), or you can program the same logic in a java file as well.
You can use Runtime to create a process and then wait for the process to finish.
You do that by doing the following.
Process process = Runtime.getRuntime().exec("cmd /c start file.bat");
int exit_value = process.waitFor();
Where in your case the file.bat is the file you want to execute.
Remove the start command to run the batch file in the foreground - then, waitFor() will wait for the batch file completion:
Process p = Runtime.getRuntime().exec("cmd /c " + path +
"\RunFromCode.bat");
If RunFromCode.bat executes the EXIT command, the command window is automatically closed. Otherwise, the command window remains open until you explicitly exit it with EXIT - the java process is waiting until the window is closed in either case.

Can java call a script to restart java in solaris?

We have a jboss application server running a webapp. We need to implement a "restart" button somewhere in the UI that causes the entire application server to restart. Our naive implementation was to call our /etc/init.d script with the restart command. This shuts down our application server then restarts it.
However, it appears that when the java process shuts down, the child process running the restart scripts dies as well, before getting to the point in the script where it starts the app server again.
We tried variations on adding '&' to the places where scripts are called, but that didn't help. Is there some where to fire the script and die without killing the script process?
Try using the nohup command to run something from within the script that you execute via Java. That is, if the script that you execute from Java currently runs this:
/etc/init.d/myservice restart
then change it to do this:
nohup /etc/init.d/myservice restart
Also, ensure that you DO NOT have stdin, stdout, or stderr being intercepted by the Java process. This could cause problems, potentially. Thus, maybe try this (assuming bash or sh):
nohup /etc/init.d/myservice restart >/dev/null 2>&1
Set your signal handlers in the restart script to ignore your signal with trap:
trap "" 2 # ignore SIGINT
trap "" 15 # ignore SIGTERM
After doing this, you'll need to kill your restart script with some other signal when needed, probably SIGKILL.

Categories