Difficulty getting object inside a CDI Extension

Asked

Viewed 83 times

1

I want to create an Extension in my project so that it starts to interpret an own annotation, for that I have initially a @Producer of the Quartz Scheduler object, see

public class SchedulerProducer {

    private static final Logger LOGGER = Logger.getLogger(SchedulerProducer.class.getName());

    private static final String SCHEDULER_CONFIGURATION_FILE = "scheduler.properties";

    private StdSchedulerFactory stdSchedulerFactory;

    @Produces
    public Scheduler createScheduler(InjectionPoint injectionPoint) {

        LOGGER.log(Level.INFO, "Criando instância do Scheduler");

        try {

            if (stdSchedulerFactory == null) {
                createStdSchedulerFactory();
            }

            return stdSchedulerFactory.getScheduler();
        } catch (Exception e) {

            LOGGER.log(Level.SEVERE, "Falha ao criar o Scheduler", e);
           return null;
        }
    }

    private void createStdSchedulerFactory() throws SchedulerException {

        Properties properties = new Properties();
        properties.putAll(getDefaultProperties());
       properties.putAll(FileUtils.loadPropertiesFile(SCHEDULER_CONFIGURATION_FILE));

        this.stdSchedulerFactory = new StdSchedulerFactory(properties);
    }

    private Properties getDefaultProperties() {

        Properties defaultProp = new Properties();
        defaultProp.put("org.quartz.scheduler.instanceId", "AUTO");
        defaultProp.put("org.quartz.jobStore.class", "org.quartz.simpl.RAMJobStore");
        defaultProp.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        defaultProp.put("org.quartz.threadPool.threadCount", "10");
        defaultProp.put("org.quartz.threadPool.threadPriority", "5");
        defaultProp.put("org.quartz.scheduler.jobFactory.class", CdiAwareJobFactory.class.getName());
        return defaultProp;
    }

}

Until then all right my doubt is how to inject into the Extension the Scheduler produced by the above class ?

Below my Extension:

public class SchedulerExtension implements Extension {

    private static final Logger LOGGER = Logger.getLogger(SchedulerExtension.class.getName());

    private Set<Class> foundManagedJobClasses = new HashSet<Class>();

    public <X> void findScheduledJobs(@Observes ProcessAnnotatedType<X> pat, BeanManager beanManager) {

        Class<X> beanClass = pat.getAnnotatedType().getJavaClass();

        if (!org.quartz.Job.class.isAssignableFrom(beanClass)) {
            return;
        }

        SchedulerJob schedulerJob = pat.getAnnotatedType().getAnnotation(SchedulerJob.class);
        if (schedulerJob != null) {
            foundManagedJobClasses.add(beanClass);
        }
    }

    public <X> void scheduleJobs(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) {

        List<String> foundJobNames = new ArrayList<String>();

        for (Class jobClass : this.foundManagedJobClasses) {

            if (foundJobNames.contains(jobClass.getSimpleName())) {
                continue;
            }

            foundJobNames.add(jobClass.getSimpleName());

            // preciso do scheduler aqui para fazero agendamento da tarefa, alguma ideia ?
        }

    }

}

Someone would know how I could take the instance of Scheduler being that it is not possible to inject it at this time yet ?

1 answer

1


According to the documentation, extensions execute before any bean is created, precisely for the purpose of being able to interfere with how they are created.

However, you can listen to events and, after initialization, access the Beans through the BeanManager.

So I would say that the process could, in theory, work as follows:

  1. Listen to the last event: AfterDeploymentValidation
  2. Retrieve the bean using BeanManager. Example:

    BeanManager bm = ...;
    Bean<T> bean = (Bean<T>) bm.getBeans(clazz).iterator().next();
    CreationalContext<T> ctx = bm.createCreationalContext(bean);
    T object = (T) bm.getReference(bean, clazz, ctx);
    

Alternatively, you can save the list of Jobs found in an attribute and process the list later in another bean. To recover the list, just inject the extension in the bean. Example:

@Inject    
MyBean(SchedulerExtension ext, Scheduler scheduler) {
    for (Class jobClass : this.foundManagedJobClasses) {    
        //scheduler...
    }
}
  • 1

    Thanks even, observing the event Afterdeploymentvalidation I managed to take the instance of my object and do what I needed, ball show.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.