Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scheduled still running after disable or undeploy my application

I'm having trouble with ManagedScheduledExecutorService. If I disable or undeploy my application the scheduler still running. It stops only when I restart the application server.

I'm using JEE, Application Server Wildfly 9 and Java8.

The following code below:

package br.com.decarli;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

import javax.annotation.Resource;
import javax.enterprise.concurrent.LastExecution;
import javax.enterprise.concurrent.ManagedScheduledExecutorService;
import javax.enterprise.concurrent.Trigger;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Destroyed;
import javax.enterprise.context.Initialized;
import javax.enterprise.event.Observes;

@ApplicationScoped
public class ApplicationSchedulerX {

@Resource( lookup = "java:jboss/ee/concurrency/scheduler/MyScheduler" )
private ManagedScheduledExecutorService timerService;

public void init( @Observes @Initialized( ApplicationScoped.class ) Object o ) {

    timerService.schedule( () -> {

        System.out.println( " Run scheduler... "  );

    }, new Trigger() {

        @Override
        public Date getNextRunTime( LastExecution le, Date date ) {
            return getNextDateBySeconds( 60 );
        }

        @Override
        public boolean skipRun( LastExecution le, Date date ) {
            return false;
        }

    } );

}

private Date getNextDateBySeconds( long seconds ) {
    LocalDateTime ldt = LocalDateTime.now().plusSeconds( seconds );
    return Date.from( ldt.atZone( ZoneId.systemDefault() ).toInstant() );
}

public void destroy( @Observes @Destroyed( ApplicationScoped.class ) Object o ) {
    //TODO error: Lifecycle operation not supported
    //timerService.shutdown();
}
}

Wildfly 9 scheduler configuration:

<managed-scheduled-executor-service name="MyScheduler" jndi-name="java:jboss/ee/concurrency/scheduler/MyScheduler" hung-task-threshold="50000" long-running-tasks="true" core-threads="4" keepalive-time="500" reject-policy="ABORT"/>
like image 866
Fabio De Carli Avatar asked Jul 29 '16 17:07

Fabio De Carli


1 Answers

I found the solution, on the link https://issues.jboss.org/browse/WFLY-3683.

I created a list of the scheduledTasks and cancel on the destroy method.

The correct code below:

package br.com.ciss.cissmart.client.core;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ScheduledFuture;

import javax.annotation.Resource;
import javax.enterprise.concurrent.LastExecution;
import javax.enterprise.concurrent.ManagedScheduledExecutorService;
import javax.enterprise.concurrent.Trigger;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Destroyed;
import javax.enterprise.context.Initialized;
import javax.enterprise.event.Observes;

@ApplicationScoped
public class ApplicationSchedulerX {

@Resource( lookup = "java:jboss/ee/concurrency/scheduler/MyScheduler" )
private ManagedScheduledExecutorService timerService;

private List<ScheduledFuture<?>> scheduledTasks;

/**
 * Método executado no start do servidor.
 *
 * @param o
 *             - {@link javax.servlet.ServletContext} - Contendo as configurações da aplicação
 */
public void init( @Observes @Initialized( ApplicationScoped.class ) Object o ) {

    this.scheduledTasks = Collections.synchronizedList(new ArrayList<ScheduledFuture<?>>());

    ScheduledFuture task =  timerService.schedule( () -> {


        System.out.println( "Run scheduler... " );

    }, new Trigger() {

        @Override
        public Date getNextRunTime( LastExecution le, Date date ) {
            return getNextDateBySeconds( 60 );
        }

        @Override
        public boolean skipRun( LastExecution le, Date date ) {
            return false;
        }

    } );

    scheduledTasks.add( task );

}

private Date getNextDateBySeconds( long seconds ) {
    LocalDateTime ldt = LocalDateTime.now().plusSeconds( seconds );
    return Date.from( ldt.atZone( ZoneId.systemDefault() ).toInstant() );
}

public void destroy( @Observes @Destroyed( ApplicationScoped.class ) Object o ) {

    // Cancel any scheduled tasks, ensuring that the map is locked.
    synchronized ( this.scheduledTasks ) {
        Iterator<ScheduledFuture<?>> i = this.scheduledTasks.iterator();

        while ( i.hasNext() ) {
            ScheduledFuture<?> future = i.next();
            // Cancel the task.
            future.cancel( true );
        }
    }
    this.scheduledTasks.clear();
    this.scheduledTasks = null;

}
}
like image 161
Fabio De Carli Avatar answered Oct 19 '22 18:10

Fabio De Carli