Difficulty getting object inside a CDI Extension

1

I want to create an extension in my project so that it starts interpreting a note itself, so I initially had 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;
    }

}

So far, my question is how to inject within 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 get the instance of the scheduler being that it is not possible to inject it at that moment yet?

    
asked by anonymous 12.11.2015 / 00:24

1 answer

1

According to documentation , extensions run before any bean be created, just for the purpose of being able to interfere in how they are created.

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

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

  • Listen for the last event: AfterDeploymentValidation
  • 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 one attribute and process the list later on another bean. To retrieve the list, just inject the extension in the bean. Example:

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