Solved

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

Posted on 2014-02-03
9
690 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
Comment Utility
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
Comment Utility
You can set CRON job in linux machine.
0
 

Author Comment

by:Rohit Bajaj
Comment Utility
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
Comment Utility
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
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 

Author Comment

by:Rohit Bajaj
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

I. Introduction There's an interesting discussion going on now in an Experts Exchange Group — Attachments with no extension (http://www.experts-exchange.com/discussions/210281/Attachments-with-no-extension.html). This reminded me of questions tha…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
This video teaches viewers about errors in exception handling.
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now