Планировщик не инициализируется при запуске приложения Google Guice. Джава - PullRequest
0 голосов
/ 04 сентября 2018

Помогите, пожалуйста, в такой ситуации. Hibernate + фреймворки Google Guice. Добавлен планировщик, задайте время выполнения каждые 10 секунд (для теста), чтобы вызывать метод searchFile (), в котором папка проверяется на наличие файлов, если папка не пустая, то мы вызываем парсер и файл разбора и, используя служба - дао - запись в базу данных. (PostgreSQL)

При запуске приложения планировщик не вызывается.

Мой класс выглядит так: interface SchedulerTask :

       import com.google.inject.ImplementedBy;

@ImplementedBy(SchedulerTaskBean.class)
public interface SchedulerTask {

    void startSchedulerTask();

    void searchFile();
}

Его реализация (SchedulerTaskBean):

    import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.io.File;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Singleton
public class SchedulerTaskBean implements Job, SchedulerTask {

    private static final Logger LOGGER = LogManager.getLogger(SchedulerTaskBean.class);

    @Inject
    private SchedulerTask schedulerTask;
    @Inject
    private CsvService csvService;

    @Override
    public void startSchedulerTask() {
        ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
        executor.scheduleWithFixedDelay(this::searchFile, 0,  10, TimeUnit.SECONDS);
//        executor.scheduleAtFixedRate(folder::searchFile, 0, 10, TimeUnit.SECONDS);
        searchFile();
    }

    public SchedulerTaskBean() {
        startSchedulerTask();
    }

    @Override
    public void searchFile() {
        Parser parser = new CsvParserFromLib();

        File dir = new File("/home/prog5/Documents/test/");
        // если объект представляет каталог
        if (dir.isDirectory()) {
            File[] listFiles= dir.listFiles();
            // Если папка не пустая - парсим что там есть, и переносим спаршеный файл в другую папку, чтоб второй раз его не спарсить.
            if(listFiles != null && listFiles.length>0){
                for (File file : listFiles) {
                    List<CsvStructureEntity> listStructure = parser.parse(file);
                    if (listStructure != null) {
                        try {
                            csvService.create(listStructure);
                        } catch (DataNotFoundException e) {
                            LOGGER.error(e);
                        }
                    } else {
                        // todo переместить файл в папку "error"
                        File badFolder = new File("/home/prog5/Documents/test/error");
                        dir.renameTo(badFolder);
                    }
                }
            }
        }
    }

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        searchFile();
    }
}

Но если вы двинетесь

    @Inject
private SchedulerTask schedulerTask;

в другом контроллере (скажем, контроллере авторизации) и запустить приложение, оно запускается и переходит в мой метод searchFile () (до точки останова), и мой сервис не имеет значение null, он работает нормально.

Помогите пожалуйста, как заставить Google Guice инициализировать мой планировщик при запуске приложения, не перенося его на другой контроллер? Чтобы он запускался автоматически при запуске приложения и, например, каждые 12 часов (сейчас для теста указано 10 секунд) мой метод?

Это мой CsvService:

    @ImplementedBy(CsvServiceBean.class)
public interface CsvService {

    List<CsvStructureEntity> create(List<CsvStructureEntity> csvStructureEntity) throws DataNotFoundException;

}
* ** 1026 1027 * CsvServiceBean:
    public class CsvServiceBean implements CsvService {

    private static final Logger LOGGER = LogManager.getLogger(CsvServiceBean.class);

    @Inject
    private CsvDao csvDao;

    @Transactional
    @Override
    public List<CsvStructureEntity> create(final List<CsvStructureEntity> csvStructureEntity) {
        csvDao.persistAll(csvStructureEntity);
        return csvStructureEntity;
    }
}

CsvDao:

     @ImplementedBy(CsvDaoBean.class)
public interface CsvDao {

    void persistAll(List<CsvStructureEntity> csvStructureEntity);
}

CsvDaoBean:

       public class CsvDaoBean extends ValidatableDaoBean<CsvStructureEntity, Long> implements CsvDao {

    private static final Logger LOGGER = LogManager.getLogger(CsvDaoBean.class);

    @Override
    protected Class<CsvStructureEntity> getEntityClass() {
        return CsvStructureEntity.class;
    }
}

ValidatableDaoBean:

    public abstract class ValidatableDaoBean<Entity, Id> extends AbstractJpaDao<Entity, Id> {

    @Override
    public void persist(final Entity entity) {
        validate(entity);
        super.persist(entity);
    }

    @Override
    public Entity merge(final Entity entity) {
        validate(entity);
        return super.merge(entity);
    }

    private void validate(Entity entity) {
        if(entity == null) {
            throw new ValidationException("Object is null.");
        }
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<Entity>> violations = validator.validate(entity);
        if(violations.size() > 0) {
            List<String> messages = new ArrayList<>();
            for (ConstraintViolation<Entity> violation : violations) {
                messages.add(violation.getMessage());
            }
            throw new ValidationException(StringUtils.join(messages, ", "));
        }
    }

    @Override
    public void persistAll(List<Entity> entities) {
        super.persistAll(entities);
    }
}

Большое спасибо заранее!

...