how to create Thread poolling using Spring scheduler? - spring

I want a sample for thread pooling using Spring scheduler?

See the The Spring TaskExecutor abstraction, use the ThreadPoolTaskExecutor. It is configured as follows:
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="queueCapacity" value="25" />
</bean>

Your question is too vague to be sure what you want, but you could use the ScheduledExecutorFactoryBean to create a standard Java5 ScheduledExecutorService which has comprehensive scheduling functions.

In Spring 3, the task namespace was added it contains what you need to setup a pooled TaskExecutor:
<task:executor id="executorWithCallerRunsPolicy"
pool-size="5-25"
queue-capacity="100"
rejection-policy="CALLER_RUNS"/>
You can read http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html for details.

Related

JTA and Hibernate Transaction management

We have implemented a spring message listener service and the main operation exposed by this service is multiple event driven database update.
The context looks like as below.
<bean id="consumerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="concurrentConsumers" value="${jms.consumerContainer.concurrentconsumers}"/>
<property name="maxConcurrentConsumers" value="${jms.consumerContainer.maxconcurrentconsumers}"/>
<property name="errorHandler" ref="errorHandler" />
<property name="connectionFactory" ref="jmsQueueConnectionFactory" />
<property name="destination" ref="listenerQueue" />
<property name="messageListener" ref="consumerContainer" />
<property name="receiveTimeout" value="10000" />
<property name="sessionTransacted" value="true" />
<property name="transactionManager" ref="txManager" />
</bean>
TX manager is hibernate.
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory"/>
and annotated the concrete class with #Transactional.
We use Jboss application server support to integrate with MQ via jndi.
The problem here is if there are any exception at any layer in the listener, the overall transaction is not getting rolled back and the message does not move to back out queue. It's obvious that as we use Hibernate transaction manager, it's not aware of other resource like JMS transactions.
Can I replace this safely with JTA transaction as Jboss will handle overall transaction management? Is there any foreseen risk in doing so?
I believe its no longer needed to annotate the class with #Transactional if we are using JTA as below.
<bean id="jtatxManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
Thanks in advance.
Can I replace this safely with JTA transaction as Jboss will handle overall transaction management?
Yes, you can. You should just change your bean txManager definition.
I believe its no longer needed to annotate the class with #Transactional.
This is not true. You still need #Transactional. It allows spring to identify a transaction boundary.

Spring boot unable to create multiple rabbit connection factories

I am trying to connect to and consume from two different clusters of rabbitmq using a spring boot app via xml. It works well when a single rabbit:connection-factory bean is created in the application context. However, when the second one is added, it fails to start the application with the error "Parameter 1 of method rabbitListenerContainerFactory in org.springframework.boot.autoconfigure.amqp.RabbitAnnotationDrivenConfiguration required a single bean, but 2 were found:". How do I go about creating different factories per cluster? Please suggest an alternative way of doing this, if it's not the right approach?
Here is the xml snippet:
<rabbit:connection-factory id="firstConnectionFactory" connection-factory="firstSpringConnectionFactory" />
<rabbit:connection-factory id="secondConnectionFactory" connection-factory="secondSpringConnectionFactory"/>
<bean id="firstSpringConnectionFactory"
class="org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean">
<property name="useSSL" value="${rabbitmq.ssl.enabled}" />
<property name="host" value="${rabbitmq.first.host}"/>
<property name="virtualHost" value="${rabbitmq.vhost}"/>
<property name="port" value="${rabbitmq.cluster.port}"/>
<property name="username" value="${rabbitmq.user}"/>
<property name="password" value="${rabbitmq.first.password}"/>
</bean>
<bean id="secondSpringConnectionFactory"
class="org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean">
<property name="useSSL" value="${rabbitmq.ssl.enabled}" />
<property name="host" value="${rabbitmq.second.host}"/>
<property name="virtualHost" value="${rabbitmq.vhost}"/>
<property name="port" value="${rabbitmq.cluster.port}"/>
<property name="username" value="${rabbitmq.user}"/>
<property name="password" value="${rabbitmq.second.password}"/>
</bean>
And the listener container code:
ConnectionFactory cf = rabbitConnectionFactory;//One of the connnection factories will be injected here from app context
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(cf);
container.setConcurrentConsumers(count);
container.addQueueNames(queueName);
container.setMessageListener(listener);
container.start();
Since you don't rely on the Spring Boot here and don't use Spring AMQP annotation support I suggest you to exclude RabbitAnnotationDrivenConfiguration from auto-configuration:
#EnableAutoConfiguration(exclude={RabbitAnnotationDrivenConfiguration.class})
spring.autoconfigure.exclude = org.springframework.boot.autoconfigure.amqp.RabbitAnnotationDrivenConfiguration
If you still need #RabbitListener somewhere in other place of your project, you only have a choice to build all the #EnableRabbit infrastructure manually.

Enabling AspectJ for a Quartz Scheduler Job

I have created bean which will be executed by a simple trigger quartz scheduler. When I enable AspectJ within my spring-context.xml , my scheduler job is not getting triggered
Here is a snippet of my spring-context.xml
<!-- Scheduler Factory -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="simpleTrigger" />
</list>
</property>
</bean>
<!-- Trigger -->
<bean id="simpleTrigger"
class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="myJobDetail" />
<!-- 30 seconds -->
<property name="startDelay" value="10000" />
<!-- repeat every 50 seconds -->
<property name="repeatInterval" value="10000" />
</bean>
<!-- Job Details -->
<bean name="myJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="test.MyJob" />
<property name="jobDataAsMap">
<map>
.....
</map>
</property>
</bean>
<aop:aspectj-autoproxy />
....
I am not an expert in spring or aop. Can someone please explain what is wrong and how can we achieve it?
Without enabling AspectJ my scheduler gets triggered properly.
Thanks.
Do you have any aspects applied to the MyJob bean? If so, perhaps the aop mechanism creates a jdk dynamic proxy that cannot be recognised by the quartz api where you specify a specific job class of type MyJob. If this assumption is correct, then try:
<aop:aspectj-autoproxy proxy-target-class="true" />
That will instead use a CGLIB-based class proxy based on MyJob class.
I recommend reading http://docs.spring.io/spring/docs/4.1.x/spring-framework-reference/html/aop.html#aop-proxying in order to understand any implications that each proxying mechanism may have.
If that was the problem, it may be better to avoid completely having an aspect around the job class itself, and perhaps putting it around a bean that the job class will call to perform the desired functionality

Spring and quartz integration with dynamic values

I am new in quartz
I am trying to integrate spring with quartz i want to take repeatInterval and startDelay dynamically is it possible.
<bean id="sampleJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="sampleJobBean" />
<property name="repeatInterval" value="5000"/>
<property name="startDelay" value="4000" />
</bean>

Implementing a process with JPA for Activiti 5.9

how can we write Spring bean with JPA logic in activiti 5.9 using oracle as back end
I'm not sure this answers your question but I'll give it a try.
You don't need to do something special to achieve your goal.
Declare you processEngine as a Spring bean, you can find information about that at Activiti user guide:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="jdbcUrl" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
<property name="jdbcDriver" value="org.h2.Driver" />
<property name="jdbcUsername" value="sa" />
<property name="jdbcPassword" value="" />
<property name="databaseSchemaUpdate" value="true" />
<property name="jobExecutorActivate" value="false" />
<property name="mailServerHost" value="mail.my-corp.com" />
<property name="mailServerPort" value="5025" />
</bean>
</beans>
After that you implement your Spring bean including JPA logic. There is nothing Activiti specific here, you just implement it like there is no Activiti. You can find details at this site. Finally you can use this bean in your Service Tasks by that method:
<serviceTask id="javaService"
name="My Java Service Task"
activiti:expression="#{printer.printMessage(myVar1, myVar2)}" />
Here, printer can be your Spring bean or just a named variable in your process context. Variables myVar1 and myVar2 are variables residing in your process context.
You can also design your JPA-logic-including-bean as an Activiti aware one by that:
<serviceTask id="serviceTask" activiti:delegateExpression="${delegateExpressionBean}" />
In this case, delegateExpressionBean is your JPA-logic-including-bean, but class of that bean must implement Activiti's JavaDelegate interface.
It is your choice.

Resources