Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting Spring task XML configuration to code configuration

I'm trying to convert XML configuration for using Spring's tasks framework into purely code configuration. I'm able to reproduce the functionality but whenever I shut down the war on the Tomcat server the task scheduler lives on, it hangs (it doesn't hang with XML configuration). I've debugged to inspect the instances of scheduler and executor but I'm not seeing a difference so I'm not sure what could be causing it to hang.

Here is the XML configuration that works:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
   http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd">

   <task:executor id="com.work.gwx.pix.executor"
      pool-size="${pix.job.executor.pool.size:1-40}"
      queue-capacity="${pix.job.executor.queue.capacity:0}"
      rejection-policy="CALLER_RUNS"/>

   <task:scheduler id="com.work.gwx.pix.scheduler" pool-size="${pix.job.scheduler.pool.size:4}"  />

    <task:annotation-driven executor="com.work.gwx.pix.executor" scheduler="com.work.gwx.pix.scheduler" />

    <bean id='queueProcessor' class="com.work.gwx.queueing.QueueProcessor" /> 

 </beans>

Here is the code configuration:

@EnableAsync
@EnableScheduling
@Configuration
public class TaskConfiguration implements AsyncConfigurer, SchedulingConfigurer {

    @Value("${pix.job.executor.max.pool.size:1}")
    private int executorMaxPoolSize;

    @Value("${pix.job.executor.queue.capacity:0}")
    private int executorQueueCapacity;

    @Value("${pix.job.scheduler.pool.size:4}")
    private int schedulerPoolSize;

    @Bean(destroyMethod = "shutdown")
    public Executor pixTaskScheduler() {
        final ScheduledThreadPoolExecutor ex = new ScheduledThreadPoolExecutor(schedulerPoolSize, new ThreadPoolTaskExecutor());
        // ex.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
        return ex;
    }

    @Bean
    public Executor pixExecutor() {
        final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(executorMaxPoolSize);
        executor.setQueueCapacity(executorQueueCapacity);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setThreadFactory(new ThreadPoolTaskExecutor());
        executor.initialize();
        return executor;
    }

    @Override
    public void configureTasks(final ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(pixTaskScheduler());

    }

    @Override
    public Executor getAsyncExecutor() {
        return pixExecutor();
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new SimpleAsyncUncaughtExceptionHandler();
    }
}

When I use setExecuteExistingDelayedTasksAfterShutdownPolicy(false) in code configuration it does shut down but I'm worried that might have adverse effects as that is set to true when done via XML configuration. Also, I should note, the QueueProcessor class is doing the work I want and I don't mind if delayed executions get cancelled -- I just don't want currently executing threads to be abruptly cancelled.

This is the message I get when it hangs:

SEVERE: The web application [/pix-queue-processor] appears to have started a thread named [ThreadPoolTaskExecutor-1] but has failed to stop it. This is very likely to create a memory leak.

Any ideas on what might be causing the hanging? Or, would using that commented out method let me do what I want (won't kill a running task but will cancel delayed tasks)?

like image 990
AHungerArtist Avatar asked May 13 '15 14:05

AHungerArtist


People also ask

Are annotations better than XML for configuring Spring?

Annotations have their use, but they are not the one silver bullet to kill XML configuration. I recommend mixing the two! For instance, if using Spring, it is entirely intuitive to use XML for the dependency injection portion of your application.

What is the difference between XML and Java configuration for Spring?

java - The Spring Boot Application class generated with Spring Initializer. This class acts as the launching point for application. pom. xml - Contains all the dependencies needed to build this project.

Does Spring boot avoid XML configuration?

Is it possible to avoid using xml in Spring or better to mix xml files and annotations? Yes, it is. Spring now promotes Java configuration, and it's perfectly doable (I'm doing it) and even easy to only use Java to configure your Spring app. Even without using Boot.

What is Spring XML configuration?

In this spring bean XML configuration example, learn to create define and create spring beans and populate application context in any spring application. This example uses xml config to define beans. We will use maven to manage the spring dependencies and eclipse to build and run the code.

How to create spring XML configuration example?

Here are simple steps to create Spring XML configuration example. 1. Create a simple java maven project. 2. Maven dependency 3. Create Bean class Create a bean class called Country.java in package org.arpit.java2blog.model .

How to create spring Hello World XML based configuration example?

In this post, we will see how to create Spring hello world XML based configuration example. Here are simple steps to create Spring XML configuration example. 1. Create a simple java maven project. 2. Maven dependency 3. Create Bean class Create a bean class called Country.java in package org.arpit.java2blog.model .

Why use @configuration instead of XML?

This still provides you a decoupling of configuration from code(like XML), but also provides other benefits like compile time checking of typos... @Configuration is your friend. Spring almost came back a full circle and moved(or intends to move) configuration from XML back to code.

What is getting error getting error in spring config file?

Getting error in spring config file error : The value of attribute "xmlns" associated with an element type "beans" must not contain the '<' character 3 Solace Connectivity issue using Spring 4.x


1 Answers

Your Java based configuration isn't really a representation of the the XML configuration. There are at least 2 things that are different.

  1. Your TaskExecutor has another TaskExecutor wired as a ThreadFactory this isn't the case in XML and also starts another TaskExecutor.
  2. Your TaskScheduler uses a new TaskExecutor whereas the xml configuration use the one configured.

The have your task finished on shutdown you can set the waitForTasksToCompleteOnShutdown property on the TaskExecutor to true then any pending tasks will be completed and no new tasks will be accepted.

Also the call to initialize shouldn't be needed as the afterPropertiesSet method will be called by Spring which in turn calls initialize.

The following 2 bean definitions are more in line with the XML configuration (and you now have a single TaskExecutor instead of 3 and it will first finish tasks before shutdown.

@Bean(destroyMethod = "shutdown")
public Executor pixTaskScheduler() {
    final ScheduledThreadPoolExecutor ex = new ScheduledThreadPoolExecutor(schedulerPoolSize, pixExecutor());
    // ex.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
    return ex;
}

@Bean
public Executor pixExecutor() {
    final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(executorMaxPoolSize);
    executor.setQueueCapacity(executorQueueCapacity);
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    executor.setWaitForTasksToCompleteOnShutdown(true);
    return executor;
}
like image 79
M. Deinum Avatar answered Oct 24 '22 09:10

M. Deinum