cron scheduler getting called twice on scheduled time of schecduler - java

This is the bean code for cron scheduler. declaration for runMeTask And runMeJob
<bean id="runMeTask" class="com.ascent.fieldomobify.cornScheduler.RunMeTask"/>
<bean name="runMeJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.ascent.fieldomobify.cornScheduler.RunMeJob" />
<property name="jobDataAsMap">
<map>
<entry key="runMeTask" value-ref="runMeTask" />
</map>
</property>
</bean>
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="runMeJob"/>
<property name="cronExpression" value="0 0 13 * * ?" />
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger" />
</list>
</property>
</bean>
it get call directly from bean scheduler configuration
The first class is RunMeJob
public class RunMeJob extends QuartzJobBean {
private RunMeTask runMeTask;
public void setRunMeTask(RunMeTask runMeTask) {
this.runMeTask = runMeTask;
}
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
try {
runMeTask.printMe();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
form here i call the controller's method which is having the logic
Second class RunMeTask
public class RunMeTask{
#Autowired
WorkOrderController workorderContoller;
public void setWorkorderContoller(WorkOrderController workorderContoller) {
this.workorderContoller = workorderContoller;
}
public void printMe() throws ParseException {
workorderContoller.printSysOut();
}
}

there are some scenarios where you can get that behavior, please check this thread: Java Spring #Scheduled tasks executing twice

Related

Unable to send Messages to Queues through Java Main Program

I am calling the sendMessage function from Main method and it gives Null Pointer Exception while creating the object Queue (this.queue).
Main method:
public void start()
{
AuthorisationServiceImpl authorisationServiceImpl = new AuthorisationServiceImpl();
try {
authorisationServiceImpl.fromMain();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
System.out.println("Starting Client Application");
AbstractApplicationContext context = new FileSystemXmlApplicationContext("resources/applicationContext.xml");
System.out.println("Spring context loaded.");
context.registerShutdownHook();
System.out.println("ShutdownHook registered.");
MainTestClient mainTestClient = new MainTestClient();
mainTestClient.start();
}
And the method that i am calling in another class is
public class AuthorisationServiceImpl {
#Autowired
private MessageSender messageSender;
private MessageReceiver messageReceiver;
private JmsTemplate jmsTemplate;
private Queue queue;
public JmsTemplate getJmsTemplate() {
return jmsTemplate;
}
public void setJmsTemplate(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
public Queue getQueue() {
return queue;
}
public void setQueue(Queue queue) {
this.queue = queue;
}
public MessageReceiver getMessageReceiver() {
return messageReceiver;
}
public void setMessageReceiver(MessageReceiver messageReceiver) {
this.messageReceiver = messageReceiver;
}
private ConfigProperties configProperties;
public void fromMain() throws InterruptedException {
System.out.println("Init method called");
String message = "AAA-MM-CCC";
long count = new Long("000001").longValue();
while (true)
{
//container.start();
StringBuffer corelationId = new StringBuffer();
if (count == 1000000) {
count = new Long("000001").longValue();
}
corelationId.append(message);
corelationId.append(String.format("%6s", String.valueOf(count)).replace(' ', '0'));
byte[] myvar = "Message".getBytes();
System.out.println("Writing message having correlationId: " + corelationId.toString() + " to the queue.");
sendMessage(corelationId.toString(),myvar);
count++;
Thread.sleep(5000);
}
}
/*public boolean sendMessage(String correlationId) throws ServiceException {
byte[] myvar = "Message".getBytes();
boolean response = false;
try {
MessageSender messageSenderVar = new MessageSender();
System.out.println("Writing message having correlationId: " + correlationId + " to the queue.");
// writing message to the request queue.
sendMessage(correlationId,myvar);
//messageReceiver.getMessage();
}catch(Exception e) {
throw new ServiceException("Exception:",e);
}
return response;
}
*/
public void sendMessage(final String correlationId, final byte[] bytes) {
this.jmsTemplate.send(this.queue, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
BytesMessage bytesMessage = session.createBytesMessage();
bytesMessage.setJMSCorrelationID(configProperties.getPREFIX_VALUE() + correlationId);
// message will follow expiration time as configured in properties
bytesMessage.writeBytes(bytes);
return bytesMessage;
}
});
System.out.println("Message " + configProperties.getPREFIX_VALUE() + correlationId + " with correlation id: " + configProperties.getPREFIX_VALUE() + correlationId + " written to the queue.");
}
public MessageSender getMessageSender() {
return messageSender;
}
public void setMessageSender(MessageSender messageSender) {
this.messageSender = messageSender;
}
public ConfigProperties getConfigProperties() {
return configProperties;
}
public void setConfigProperties(ConfigProperties configProperties) {
this.configProperties = configProperties;
}
}
I am getting Null Pointer Exception while calling sendMessage Method. Is there any problem in calling the non static methods from Static Method?
Starting Client Application
Nov 23, 2015 12:49:53 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext#5ba28182: startup date [Mon Nov 23 12:49:53 UTC 2015]; root of context hierarchy
Nov 23, 2015 12:49:53 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from file [/app/dev-data/node1/support/tactical_tools/gwatest/client1/resources/applicationContext.xml]
Nov 23, 2015 12:49:54 PM org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
INFO: Loading properties file from URL [file:resources/config.properties]
Nov 23, 2015 12:49:54 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#6b915330: defining beans [propertyConfigurer,configProperties,jndiTemplate,connectionFactory,paymentRequestQueue,paymentResponseQueue,jmsTemplate,messageSender,authorisationResponseHandler,authorisationServiceImpl,jmsContainer]; root of factory hierarchy
Nov 23, 2015 12:49:55 PM org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup start
INFO: Starting beans in phase 2147483647
Spring context loaded.
ShutdownHook registered.
Init method called
Writing message having correlationId: AAA-MM-CCC000001 to the queue.
Exception in thread "main" java.lang.NullPointerException
at aero.sita.uatp.client.AuthorisationServiceImpl.sendMessage(AuthorisationServiceImpl.java:114)
at aero.sita.uatp.client.AuthorisationServiceImpl.fromMain(AuthorisationServiceImpl.java:86)
at aero.sita.uatp.client.MainTestClient.start(MainTestClient.java:15)
at aero.sita.uatp.client.MainTestClient.main(MainTestClient.java:31)
When i call the sendMessage Normally without Main Method then i am able to connect successfully. And i am using the Spring ApplicationContext to initialize queues as below
<!-- Config property -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>file:resources/config.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="order" value="0" />
</bean>
<!-- App config properties -->
<bean id="configProperties" class="aero.sita.uatp.server.utilities.ConfigProperties">
<property name="properties">
<props>
<prop key="prefix.correlation">${prefix.correlation}</prop>
</props>
</property>
</bean>
<!-- jndi Template -->
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">${broker.initialContexFactory}</prop>
<prop key="java.naming.provider.url">${broker.provide.url}</prop>
</props>
</property>
</bean>
<!-- JMS Connection factory -->
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>${broker.connectionFactory}</value>
</property>
</bean>
<!-- Auth (Payment) Request queue -->
<bean id="paymentRequestQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>${payment.request}</value>
</property>
</bean>
<!-- Auth (Payment) Response queue -->
<bean id="paymentResponseQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>${payment.response}</value>
</property>
</bean>
<!-- JMS Template -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="explicitQosEnabled" value="true" />
<property name="timeToLive" value="${payment.request.expiration}" />
<property name="receiveTimeout" value="${payment.response.receive.timeout}" />
</bean>
<bean id="messageSender" class="aero.sita.uatp.server.MessageSender">
<property name="jmsTemplate" ref="jmsTemplate" />
<property name="queue" ref="paymentResponseQueue" />
<property name="configProperties" ref="configProperties" />
</bean>
<bean id="authorisationServiceImpl" class="aero.sita.uatp.server.AuthorisationServiceImpl">
<property name="messageSender" ref="messageSender" />
<property name="configProperties" ref="configProperties" />
</bean>
<bean id="authorisationResponseHandler" class="aero.sita.uatp.server.AuthorisationResponseHandler">
<property name="configProperties" ref="configProperties" />
<property name="messageSender" ref="messageSender" />
</bean>
<!-- and this is the message listener container -->
<bean id="jmsContainer" class="org.springframework.jms.listener.SimpleMessageListenerContainer">
<property name="autoStartup" value="TRUE" />
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="paymentRequestQueue" />
<property name="messageListener" ref="authorisationResponseHandler" />
</bean>
You are getting a NullPointerException when trying to invoke this.jmsTemplate.send(...) method, because your jmsTemplate variable is NULL, or never initialized. One more thing is that you are not using the spring bean authorisationServiceImpl, but you are instantiating the class manually.
First you need to set the jmsTemplate in your bean:
<bean id="authorisationServiceImpl" class="aero.sita.uatp.server.AuthorisationServiceImpl">
<property name="jmsTemplate" ref="jmsTemplate" />
<property name="messageSender" ref="messageSender" />
<property name="configProperties" ref="configProperties" />
</bean>
Second you should not instantiate the class:
AuthorisationServiceImpl authorisationServiceImpl = new AuthorisationServiceImpl();
try {
authorisationServiceImpl.fromMain();
}
But get it from application context, that you have just created
AuthorisationServiceImpl authorisationServiceImpl = context.getBean("authorisationServiceImpl", AuthorisationServiceImpl.class );

Spring Hibernate + AOP

Help! I'm using Spring+Hibernate and I'm trying to use AOP like this :
package ua.i.pustovalov.table;
enter code here
#Aspect
public class Aoprad {
#Pointcut("execution(* *getAll(..))")
public void performance() {
}
public Aoprad() {
}
#Around("performance()")
public void AfterAndPriv(ProceedingJoinPoint joinPoint) {
try {
System.out.println("Open query");
joinPoint.proceed();
System.out.println("Close query");
} catch (Throwable e) {
e.printStackTrace();
}
}
}
When I try to use my method, it returns null.
public class TestDao {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "applicationContext.xml" }, true);
DaoInterface das = (DaoInterface) context.getBean("dataDao");
System.out.println(das.getAll());
}
<context:annotation-config />
<aop:aspectj-autoproxy />
<context:component-scan base-package="ua.i.pustovalov.*">
</context:component-scan>
<bean id="audience" class="ua.i.pustovalov.table.Aoprad" />
<aop:config>
<aop:pointcut id="myPointcut"
expression="execution(* ua.i.pustovalov.maven.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- <tx:method name="get*" propagation="REQUIRED" read-only="true" /> -->
<tx:method name="getAll*" propagation="REQUIRED" read-only="true" />
</tx:attributes>
</tx:advice>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/homebase</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value></value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:/hibernate.cfg.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">create</prop> -->
</props>
</property>
</bean>
<bean id="dataDao" class="ua.i.putsovalov.dao.DaoStudent">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
My DAO class
package ua.i.putsovalov.dao;
public class DaoStudent extends HibernateDaoSupport implements DaoInterface {
public DaoStudent() {
}
#Override
protected HibernateTemplate createHibernateTemplate(
SessionFactory sessionFactory) {
HibernateTemplate result = super
.createHibernateTemplate(sessionFactory);
result.setAllowCreate(true);
return result;
}
#Override
public Student get(int id) {
return (Student) getSession().get(Student.class, id);
}
#Override
public Student get(String text) {
return (Student) getSession().get(Student.class, text);
}
#SuppressWarnings("unchecked")
#Override
public Collection<Student> getAll() {
return getSession().createCriteria(Student.class).list();
}
}
And interface
public interface DaoInterface {
Student get(int id);
Student get(String text);
Collection<Student> getAll();
}
What steps can I take to debug this issue?
When using an around aspect you should always use a method signature that returns Object and not void and you should always return the result of the call to the proceed() method. If you fail to do so every method that is advices by this aspect will return null because there is nothing returned.
#Around("performance()")
public Object AfterAndPriv(ProceedingJoinPoint joinPoint) {
try {
System.out.println("Open query");
return joinPoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
} finally {
System.out.println("Close query");
}
}

Spring batch integration

I am looking for a guidance/solution with Spring batch integration. I have a directory to which external application will send xml files. My application should read the file content and move the file to another directory.
The application should be able to process the files in parallel.
Thanks in advance.
You can use Spring Integration ftp / sftp combined with Spring Batch:
1.Spring Integration Ftp Configuration :
<bean id="ftpClientFactory"
class="org.springframework.integration.ftp.session.DefaultFtpSessionFactory">
<property name="host" value="${host.name}" />
<property name="port" value="${host.port}" />
<property name="username" value="${host.username}" />
<property name="password" value="${host.password}" />
<property name="bufferSize" value="100000"/>
</bean>
<int:channel id="ftpChannel" />
<int-ftp:outbound-channel-adapter id="ftpOutbound"
channel="ftpChannel" remote-directory="/yourremotedirectory/" session-factory="ftpClientFactory" use-temporary-file-name="false" />
2.Create your reader and autowire a service to provide your items if needed :
#Scope("step")
public class MajorItemReader implements InitializingBean{
private List<YourItem> yourItems= null;
#Autowired
private MyService provider;
public YourItem read() {
if ((yourItems!= null) && (yourItems.size() != 0)) {
return yourItems.remove(0);
}
return null;
}
//Reading Items from Service
private void reloadItems() {
this.yourItems= new ArrayList<YourItem>();
// use the service to provide your Items
if (yourItems.isEmpty()) {
yourItems= null;
}
}
public MyService getProvider() {
return provider;
}
public void setProvider(MyService provider) {
this.provider = provider;
}
#Override
public void afterPropertiesSet() throws Exception {
reloadItems();
}
}
3. Create Your Own Item Processor
public class MyProcessor implements
ItemProcessor<YourItem, YourItem> {
#Override
public YourItem process(YourItem arg0) throws Exception {
// Apply any logic to your Item before transferring it to the writer
return arg0;
}
}
4. Create Your Own Writer :
public class MyWriter{
#Autowired
#Qualifier("ftpChannel")
private MessageChannel messageChannel;
public void write(YourItem pack) throws IOException {
//create your file and from your Item
File file = new File("the_created_file");
// Sending the file via Spring Integration Ftp Channel
Message<File> message = MessageBuilder.withPayload(file).build();
messageChannel.send(message);
}
5.Batch Configuration :
<bean id="dataSourcee"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="" />
<property name="url" value="" />
<property name="username" value="" />
<property name="password" value="" />
</bean>
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
<property name="dataSource" ref="dataSourcee" />
<property name="transactionManager" ref="transactionManagerrr" />
<property name="databaseType" value="" />
</bean>
<bean id="transactionManagerrr"
class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
6.Another ApplicationContext file to Configure Your Job :
<context:annotation-config />
<bean id="provider" class="mypackage.MyService" />
<context:component-scan base-package="mypackage" />
<bean id="myReader" class="mypackage.MyReader"
<property name="provider" ref="provider" />
</bean>
<bean id="myWriter" class="mypackage.MyWriter" />
<bean id="myProcessor" class="mypackage.MyProcessor" />
<bean id="mReader"
class="org.springframework.batch.item.adapter.ItemReaderAdapter">
<property name="targetObject" ref="myReader" />
<property name="targetMethod" value="read" />
</bean>
<bean id="mProcessor"
class="org.springframework.batch.item.adapter.ItemProcessorAdapter">
<property name="targetObject" ref="myProcessor" />
<property name="targetMethod" value="process" />
</bean>
<bean id="mWriter"
class="org.springframework.batch.item.adapter.ItemWriterAdapter">
<property name="targetObject" ref="myWriter" />
<property name="targetMethod" value="write" />
</bean>
<batch:job id="myJob">
<batch:step id="step01">
<batch:tasklet>
<batch:chunk reader="mReader" writer="mWriter"
processor="mProcessor" commit-interval="1">
</batch:chunk>
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="myRunScheduler" class="mypackage.MyJobLauncher" />
<task:scheduled-tasks>
<task:scheduled ref="myJobLauncher" method="run"
cron="0 0/5 * * * ?" />
<!-- this will maker the job runs every 5 minutes -->
</task:scheduled-tasks>
7.Finally Configure A launcher to launch your job :
public class MyJobLauncher {
#Autowired
private JobLauncher jobLauncher;
#Autowired
#Qualifier("myJob")
private Job job;
public void run() {
try {
String dateParam = new Date().toString();
JobParameters param = new JobParametersBuilder().addString("date",
dateParam).toJobParameters();
JobExecution execution = jobLauncher.run(job, param);
execution.stop();
} catch (Exception e) {
e.printStackTrace();
}
}

spring3 - application context - bean property name and reference - null pointer exception

All - In the Spring 3.0, in the applicationContext.xml .... are we supposed to have the bean property name and the reference value to be the same ? If I give a different value, it returns null object. But on giving the same value, it works. For my project, i am supposed to give different values for them. Kindly help. bye, HS
This works: (same values)
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="cacheDelegate" />
</property>
</bean>
This doesn't work: (different values)
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="MNCCacheDelegate" />
</property>
</bean>
bye, HS
My Full Code here:
WIRAdminBaseAction.java ---> my base action
AuthenticateAction.java ---> my java file that calls the bean here
applicationContext.xml --> system's applicationcontext file
applicationContext_MNC.xml ---> my applicationContext for a specific company ... this is getting loaded by my java file, which gets invoked by the web.xml file.
CacheDelegate.java
StatusDBDAO.java
PreXMLWebApplicationContext.java ----> loads my applicationContext file for the specific company.
****** applicationContext.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<bean name="exceptionHandler" class="com.megasoft.wir.eStatement.web.interceptor.WIRExceptionHandlerInterceptor"/>
<bean name="security" class="com.megasoft.wir.eStatement.web.interceptor.SecurityInterceptor"/>
<bean name="permission" class="com.megasoft.wir.eStatement.web.interceptor.PermissionInterceptor"/>
<!-- AutoProxies -->
<bean name="loggingAutoProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>base</value>
<value>exceptionHandler</value>
<value>security</value>
<value>permission</value>
</list>
</property>
</bean>
</beans>
****** applicationContext_MNC.xml ******
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="MNCCacheDelegate" />
</property>
</bean>
<bean id="MNCCacheDelegate" class="com.megasoft.wiradmin.delegate.CacheDelegate" >
<property name="statusDBDAO"><ref bean="MNCStatusDBDAO" /></property>
</bean>
<bean id="MNCStatusDBDAO" class="com.megasoft.wiradmin.dao.StatusDBDAO">
<property name="dataSource">
<ref bean="MNCAdminDataSource" />
</property>
</bean>
<!-- database configuration from property file -->
<bean id="MNCAdminDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" lazy-init="default" autowire="default" dependency-check="default">
<property name="driverClass" value="${jdbc.driver}" ></property>
<property name="jdbcUrl" value="${admin.jdbc.url}" ></property>
<property name="user" value="${admin.jdbc.user}" ></property>
<property name="password" value="${admin.jdbc.password}" ></property>
<property name="initialPoolSize" value="3" ></property>
<property name="minPoolSize" value="3" ></property>
<property name="maxPoolSize" value="25" ></property>
<property name="acquireIncrement" value="1" ></property>
<property name="acquireRetryDelay" value="1000" ></property>
<property name="debugUnreturnedConnectionStackTraces" value="true" ></property>
<property name="maxIdleTime" value="300" ></property>
<property name="unreturnedConnectionTimeout" value="300000" ></property>
<property name="preferredTestQuery" value="SELECT COUNT(*) FROM LOCALE_CODE" ></property>
<property name="checkoutTimeout" value="300000" ></property>
<property name="idleConnectionTestPeriod" value="600000" ></property>
</bean>
<!-- this bean is set to map the constants which needs to be configured as per
the environment to the java constants file -->
<bean id="envConstantsConfigbean" class="com.megasoft.wiradmin.util.constants.Environm entConstantsSetter">
<property name="loginUrl" value="${login.url}"/>
<property name="logoutIR" value="${logout.from.image.retrieval}"/>
<property name="adminModuleUrl" value="${admin.url}"/>
<property name="adminUrlSym" value="${admin.url.sym}"/>
<property name="envProperty" value="${env.property}"/>
</bean>
</beans>
****** AuthenticateAction.java ******
package com.megasoft.wiradmin.web.action;
import java.net.UnknownHostException;
import java.sql.SQLException;
import org.bouncycastle.crypto.CryptoException;
import org.springframework.context.ApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.web.context.support.WebApplica tionContextUtils;
import com.megasoft.wiradmin.delegate.ICacheDelegate;
public class AuthenticateAction extends WIRAdminBaseAction {
private static final long serialVersionUID = 1L;
public String authenticate() throws UnknownHostException, CryptoException,
DataAccessException, SQLException{
/** This way of calling works...... This is not encouraged, as we should not use applicationContext always **/
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContex t(getServletRequest().getSession().getServletConte xt());
ICacheDelegate cacheAction = (ICacheDelegate) applicationContext.getBean("MNCCacheDelegate");
/** The below way of calling does NOT work .... returns null value.... Please help...
* I assume that, since I have extended the WIRAdminBaseAction, i should be able to call the getCacheDelegate directly
* and it should return my cacheDelegate object ...
* Again, Please note.....if I change my applicationContext_MNC.xml as below, the below way of calling works fine...
* but, i don't want to change my applicationContext_MNC.xml as below, due to some necessity.
*
<bean id="MNCWIRAdminBaseAction" class="com.megasoft.wiradmin.web.action.WIRAdminBaseAction">
<property name="cacheDelegate">
<ref bean="cacheDelegate" />
</property>
</bean>
*
<bean id="cacheDelegate" class="com.megasoft.wiradmin.delegate.CacheDelegate" >
<property name="statusDBDAO"><ref bean="MNCStatusDBDAO" /></property>
</bean>
*
... is it that the name and bean should have the same value.... ??? No Need to be.....Am i right ? Please advise.
*
* **/
getCacheDelegate().getActorAction(1); // this way of calling doesn't work and returns null value. please help.
return "success";
}
}
****** WIRAdminBaseAction.java ******
package com.megasoft.wiradmin.web.action;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.config.entities.Parameteri zable;
import com.megasoft.wiradmin.delegate.ICacheDelegate;
public class WIRAdminBaseAction extends ActionSupport implements Preparable, ParameterAware, Parameterizable, SessionAware,RequestAware {
private HttpServletRequest request;
private static final long serialVersionUID = 1L;
private HttpServletResponse response;
private ICacheDelegate cacheDelegate;
private Map session;
private Map<String, String> params;
private Map parameters;
public void prepare() throws Exception {
}
public String execute() throws Exception {
return SUCCESS;
}
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public HttpServletRequest getServletRequest() {
return this.request;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
public HttpServletResponse getServletResponse() {
return this.response;
}
public ICacheDelegate getCacheDelegate() {
return cacheDelegate;
}
public void setCacheDelegate(ICacheDelegate cacheDelegate) {
this.cacheDelegate = cacheDelegate;
}
public void addParam(final String key, final String value) {
this.params.put(key, value);
}
public Map getParams() {
return params;
}
public void setParams(final Map<String, String> params) {
this.params = params;
}
public Map getSession() {
return this.session;
}
public void setSession(final Map session) {
this.session = session;
}
public void setParameters(final Map param) {
this.parameters = param;
}
}
PreXMLWebApplicationContext.java **
package com.megasoft.wiradmin.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.support.XmlWebApplicationContext;
public class PreXMLWebApplicationContext extends XmlWebApplicationContext {
/**
* This initializes the Logger.
*/
private static Log logger = LogFactory.getLog(PreXMLWebApplicationContext.class);
protected String[] getDefaultConfigLocations() {
String environment = System.getProperty("envProperty");
String webirConfig = System.getProperty("webirConfig");
String fi = System.getProperty("FI");
String preHostConfiguration =null;
logger.info("The environment is "+environment);
logger.info("The webirConfig is "+webirConfig);
logger.info("The fi is "+fi);
if(environment != null && webirConfig != null && fi != null) {
preHostConfiguration = DEFAULT_CONFIG_LOCATION_PREFIX +
"classes/applicationContext" + "_" + fi.toUpperCase() +
DEFAULT_CONFIG_LOCATION_SUFFIX;
}
return new String[]{DEFAULT_CONFIG_LOCATION, preHostConfiguration};
}
/**
* This is close API.
*
* #see org.springframework.context.support.AbstractApplicationContext
* #close()
*/
public void close() {
this.doClose();
logger.info("Login-->into the closed");
}
}
<property name="userDelegate" ref="userDelegate" />
name is the field name in your class. When name is userDelegate, it means that WIRAdminBaseAction has a field named userDelegate (and probably a setter setUserDelegate())
ref is the bean name you want to set this field to. In your example, you should have another bean, named userDelegate or bmoUserDelegate which should be set as userDelegate in WIRAdminBaseAction.
So if you want to use the second configuration:
You just need to create a bean with id bmoUserDelegate:
<bean id="bmoUserDelegate" class="mypackage.BmoUserDelegateClass"/>

Read/write to database from quartz jobs - transactions not working

I have two Quartz (1.8.3) jobs, configured via Spring (2.5.6), one of them writes (send) to database, and one reads from it (check).
<bean id="scheduleFactory"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="Check"/>
<ref bean="Send"/>
</list>
</property>
</bean>
<bean id="Send" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="StatusMonitor" />
<property name="targetMethod" value="sendMessage" />
</bean>
</property>
<property name="cronExpression" value="0 0/1 * * * ?" />
</bean>
<bean id="Check" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="StatusMonitor" />
<property name="targetMethod" value="checkAndUpdateStatus" />
</bean>
</property>
<property name="cronExpression" value="30 0/1 * * * ?" />
</bean>
Transaction manager is set up:
<tx:annotation-driven transaction-manager="TransactionManager"/>
In both jobs I explicitly run read/write operations in transactions like this:
#Override
public synchronized void sendMessage() {
try {
TransactionTemplate tt = new TransactionTemplate(ptm);
tt.execute(new TransactionCallbackWithoutResult() {
#Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
...
statusDAO.update(status);
...
}
});
log.info("Status was updated");
} catch (Exception e) {
...
}
}
where ptm is a TransactionManager bean, injected via Spring.
I see "Status was updated" record in logs, but when I read this record from transactional read method it is outdated sometimes. Moreover, when I use an SQL editor to read this record it is outdated too.
I don't understand, why transactions dont work in this case, do you have any ideas?
Thanks.
For anyone that might be interested. This worked for me
<bean name="applicationDataCollectorControllerJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="org.mypckage.controller.jobs.ApplicationDataCollectorController" />
<property name="jobDataAsMap">
<map>
<!--<entry key="timeout" value="1" />-->
<entry key="genericService" value-ref="genericService" />
<entry key="applicationDataCollectorService" value-ref="applicationDataCollectorService" />
<entry key="transactionManager" value-ref="transactionManager" />
</map>
</property>
</bean>
--- in the scheduler bean---
#Override
protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException {
getApplicationDataCollectorService().collectData(transactionManager);
}
----In the applicationDataCollectorService bean-----
public void collectData( org.springframework.transaction.jta.JtaTransactionManager transactionManager) {
try {
this.transactionManager = transactionManager;
testTransactionalSave();
} catch (Exception e) {
BUSY = false;
e.printStackTrace();
}
}
}
private void testTransactionalSave() throws Exception {
TransactionTemplate tt = new TransactionTemplate(transactionManager);
tt.execute(new TransactionCallbackWithoutResult() {
#Override
protected void doInTransactionWithoutResult(TransactionStatus ts) {
try {
ApplicationParameter appPara = null;
List<ApplicationParameter> appParaList = genericService.getListFromHQL("select o from ApplicationParameter as o order by o.id desc", false);
if (appParaList != null) {
if (appParaList.size() > 0) {
appPara = (ApplicationParameter) appParaList.get(0);
appPara.setLastBankStatementMailNum(appPara.getLastBankStatementMailNum() + 10);
appPara = (ApplicationParameter) genericService.mergeObject(appPara);
System.out.println(" num is now = " + appPara.getLastBankStatementMailNum());
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
Note: dont forget to declare transactionManager as private properties in both beans with public setter and getter for spring to wire it up. Any Questions? yemiosigbesan#gmail.com

Categories