Solved

Deploying a java spring process in linux at a certain time everyday even if the system restarts

Posted on 2014-02-03
9
724 Views
Last Modified: 2014-02-05
HI,
I have a java spring project with the following root-context.xml :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<!-- Root Context: defines shared resources accessible to all other web 
		components -->
	<context:component-scan base-package="com.yatra">
		<context:exclude-filter type="annotation"
			expression="org.springframework.stereotype.Controller" />
	</context:component-scan>

	
	<bean id="yatraDB" class="com.yatra.extremesearch.DBTemplate.DBTemplate">
		<constructor-arg index="0" ref="yatraDataSource" />
	</bean>

	<bean id="yatraDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<property name="driverClass" value="${yatra.jdbc.driver}" />
		<property name="jdbcUrl" value="${yatra.jdbc.url}" />
		<property name="user" value="${yatra.jdbc.username}" />
		<property name="password" value="${yatra.jdbc.password}" />
		<property name="acquireIncrement" value="${yatra.acquire.increment}" />
		<property name="minPoolSize" value="${yatra.min.pool.size}" />
		<property name="maxPoolSize" value="${yatra.max.pool.size}" />
		<property name="maxStatementsPerConnection" value="${yatra.max.statements}" />
		<property name="numHelperThreads" value="${yatra.num.helper.threads}" />
		<property name="idleConnectionTestPeriod" value="300" />
		<property name="preferredTestQuery" value="SELECT 0" />
	</bean>
	
	<!-- Define Job beans -->
    <bean id="extremeSearchJob" class="com.yatra.extremesearch.job.ExtremeSearchJob" />
    
     <!-- create the Job -->
    <bean id="extremeSearchJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="extremeSearchJob" />
        <property name="targetMethod" value="execute" />
    </bean>
    
    <!-- create the Trigger with a Schedule -->
    <bean id="extremeSearchJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail" ref="extremeSearchJobDetail" />
        <property name="cronExpression" value="0 45 13 * * ? *" />  <!-- Every 5 minutes -->
    </bean>
    
    <!-- schedule the Job -->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    	<property name="triggers">
		    <list>
		    	<ref bean="extremeSearchJobTrigger"/>
		    </list>
		</property>
		<property name="quartzProperties">  
                <props>  
            <prop key="org.quartz.scheduler.skipUpdateCheck">true</prop>  
          </props>  
     </property> 
    </bean>

	<!-- <bean id="searchService" class="com.yatra.extremesearch.service.impl.SearchParamServiceImpl">
	</bean> -->
	
	<bean id="httpConnectionManagerParams" class="org.apache.commons.httpclient.params.HttpConnectionManagerParams">
		<property name="soTimeout" value="1000000" />
		<property name="connectionTimeout" value="1000000" />
	</bean>

	<bean id="multiThreadedHttpConnectionManager" class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager">
		<property name="params" ref="httpConnectionManagerParams" />
	</bean>


	<bean id="httpClient" class="org.apache.commons.httpclient.HttpClient">
		<constructor-arg index="0" ref="multiThreadedHttpConnectionManager" />
	</bean>

	<bean id="httpService" class="com.yatra.platform.http.HttpService">
		<constructor-arg index="0" ref="httpClient" />
	</bean>

	<import resource="properties.xml" />
	<import resource="thread-pool.xml" />

</beans>
	

Open in new window


I run the project using the following command :

nohup /data/ytxdist/java/latest/bin/java -cp "libs/*:conf:libs/yatra_extremesearch.jar" com.yatra.extremesearch.app.ExtremeSearchApp &

This process run everyday at a certain time.
The problem is that if the linux machine on which i have deployed this restarts then
i need to again go to the machine manually and reschedule the process.

How do i configure it in such a way so that the process automatically starts once the machine is restarted

Thanks
0
Comment
Question by:Rohit Bajaj
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
9 Comments
 
LVL 8

Expert Comment

by:Surrano
ID: 39831760
Since you added the tag "cronjob" I assume you are familiar with the cron functionality. My question is:
- Do you have problems using it?
- Or you have no problems but it doesn't work for some reason?
- Or it works but you need some additional functionality?

E.g. if cron job is scheduled for 3:00 AM but the system is down from 2:40 to 6:00 then it should automatically start at 6:01 and then again at 3:00 afterwards? I recommend two approaches for this:

A) make a cron job, kind of watchdog, that checks the last execution time of the spring project every five minutes and if it was 23:56 hours or more ago then start it

B) leave the original cron job at 3:00AM and create an init script that checks when the system was last up. If there was a missed run during the downtime then start it.

If you like either approach I can help implement it.
0
 
LVL 6

Expert Comment

by:Mahesh Bhutkar
ID: 39831798
You can set CRON job in linux machine.
0
 

Author Comment

by:Rohit Bajaj
ID: 39832021
Hi Surrano,
Please help me with (A) approach.
My project runs properly at 3 every day. But problem to be solved is the same as you mentioned. If the process stops for some random reason or the system was restarted or down then it wont run in the future in some cases or a run will get skipped.
0
NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

 
LVL 8

Accepted Solution

by:
Surrano earned 400 total points
ID: 39832054
OK so once again:
you start the project like this *once*:
nohup /data/ytxdist/java/latest/bin/java -cp "libs/*:conf:libs/yatra_extremesearch.jar" com.yatra.extremesearch.app.ExtremeSearchApp &

Open in new window

and it keeps running for several days, triggering the configured job every day. Right?

All you need is a script that peroidically checks whether it's running and start it as needed?

Create a script called e.g. "es_watchdog.sh" and put it to e.g. "/usr/local/bin"

#!/bin/bash
PATH="$PATH:/bin"
ps -ef | grep '/data/ytxdist/java/latest/bin/java.*com.yatra.extremesearch.app.ExtremeSearchApp' >/dev/null
if [ $? -ne 0 ]; then
  nohup /data/ytxdist/java/latest/bin/java -cp "libs/*:conf:libs/yatra_extremesearch.jar" com.yatra.extremesearch.app.ExtremeSearchApp &
fi

Open in new window


Make it executable and put it into crontab of the given user using command "crontab -e" and adding the following line:
*/5 * * * * /usr/local/bin/es_watchdog.sh

Open in new window


Note that the notation "*/5" meaning "every five minutes" may not work in your OS; in that case , use this line: (make sure that there'll be no spaces around commas!)
0,5,10,15,20,25,30,35,40,45,50,55 * * * *  /usr/local/bin/es_watchdog.sh

Open in new window

0
 

Author Comment

by:Rohit Bajaj
ID: 39834845
Hi,
The above script is not working.
The reason for this probably is that when i run the following command on my terminal i get the output as mentioned below :

 ps -ef | grep '/data/ytxdist/java/latest/bin/java.*com.yatra.extremesearch.app.ExtremeSearchApp'
yatra     9210  8966  0 12:55 pts/0    00:00:00 grep /data/ytxdist/java/latest/bin/java.*com.yatra.extremesearch.app.ExtremeSearchApp


That means the ps command is itself including the grep command in the running process list so that even though the process is not running it still shows as if it is running

Regards
Robin
0
 
LVL 8

Expert Comment

by:Surrano
ID: 39834973
Sorry for the oversight; I had it in mind but failed to put it into the code.

#!/bin/bash
PATH="$PATH:/bin"
ps -ef | grep '/data/ytxdist/java/lates[t]/bin/java.*com.yatra.extremesearch.app.ExtremeSearchApp' >/dev/null
if [ $? -ne 0 ]; then
  nohup /data/ytxdist/java/latest/bin/java -cp "libs/*:conf:libs/yatra_extremesearch.jar" com.yatra.extremesearch.app.ExtremeSearchApp &
fi

Open in new window

0
 

Author Comment

by:Rohit Bajaj
ID: 39835027
Hi,
I am using your script but not in the same directory as you mentioned. I copied the .sh to
the location :
/data/yatra/SCHEDULER/ExtremeSearch

Under this location i did crontab -e and in the editor i have the following :
0,5,10,15,20,25,30,35,40,45,50,55 * * * * /data/yatra/SCHEDULER/ExtremeSearch/watch.sh

I tried */5 also

But the process didnt started in 5 minutes or even after some time.
But when i run my script manually it works.

Do i need a system restart to get the crontab working ? or the .sh file needs to be in /usr/local/bin ?

thanks
0
 

Author Comment

by:Rohit Bajaj
ID: 39835282
Here is the ouput of crontab -l :

* * * * * /data/yatra/SCHEDULER/ExtremeSearch/watch.sh> /data/yatra/SCHEDULER/ExtremeSearch/1.log 2>&1


I see 1.log created with the following message :

Exception in thread "Main Thread" java.lang.NoClassDefFoundError: com/yatra/extremesearch/app/ExtremeSearchApp
Could not find the main class: com.yatra.extremesearch.app.ExtremeSearchApp.  Program will exit.

It looks like some path issue but the script runs perfectly when i run it manually.
0
 
LVL 35

Assisted Solution

by:mccarl
mccarl earned 100 total points
ID: 39835317
Try adding the following line just before the nohup line in the watch.sh script ...
cd /data/yatra/SCHEDULER/ExtremeSearch

Open in new window

The problem is that when you run the script manually, the current directory that you are in is correct for those relative paths in your classpath (-cp argument). But when cron runs the script, the current working directory will be different. So the "cd" command sorts that out. Alternatively, you would need to use the full paths in your classpath argument.
0

Featured Post

Resolve Critical IT Incidents Fast

If your data, services or processes become compromised, your organization can suffer damage in just minutes and how fast you communicate during a major IT incident is everything. Learn how to immediately identify incidents & best practices to resolve them quickly and effectively.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Linux users are sometimes dumbfounded by the severe lack of documentation on a topic. Sometimes, the documentation is copious, but other times, you end up with some obscure "it varies depending on your distribution" over and over when searching for …
The purpose of this article is to demonstrate how we can use conditional statements using Python.
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
This video teaches viewers about errors in exception handling.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question