Solved

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

Posted on 2014-02-03
9
703 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
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
 
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
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 

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

What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

Question has a verified solution.

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

Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Join Greg Farro and Ethan Banks from Packet Pushers (http://packetpushers.net/podcast/podcasts/pq-show-93-smart-network-monitoring-paessler-sponsored/) and Greg Ross from Paessler (https://www.paessler.com/prtg) for a discussion about smart network …
This video teaches viewers about errors in exception handling.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

919 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now