apache / dubbo

The java implementation of Apache Dubbo. An RPC and microservice framework.
https://dubbo.apache.org/
Apache License 2.0
40.39k stars 26.41k forks source link

dubbo + quartz + spring NPE #2429

Closed lzimd closed 6 years ago

lzimd commented 6 years ago

Environment

Actual Result

org.quartz.SchedulerException: Job instantiation failed
    at org.springframework.scheduling.quartz.AdaptableJobFactory.newJob(AdaptableJobFactory.java:47) ~[spring-context-support-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.quartz.core.JobRunShell.initialize(JobRunShell.java:127) ~[quartz-2.3.0.jar:na]
    at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:392) [quartz-2.3.0.jar:na]
Caused by: java.lang.NullPointerException: null
    at com.alibaba.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor.postProcessBeforeInitialization(DubboConfigBindingBeanPostProcessor.java:78) ~[dubbo-2.6.2.jar:2.6.2]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:423) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1702) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:414) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.boot.autoconfigure.quartz.AutowireCapableBeanJobFactory.createJobInstance(AutowireCapableBeanJobFactory.java:45) ~[spring-boot-autoconfigure-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.scheduling.quartz.AdaptableJobFactory.newJob(AdaptableJobFactory.java:43) ~[spring-context-support-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    ... 2 common frames omitted
  1. org.springframework.scheduling.quartz.AdaptableJobFactory.newJob
    public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException {
    try {
        Object jobObject = createJobInstance(bundle);
        return adaptJob(jobObject);
    }
    catch (Throwable ex) {
        throw new SchedulerException("Job instantiation failed", ex);
    }
    }
  2. initializeBean(beanName = null) org.springframework.boot.autoconfigure.quartz.AutowireCapableBeanJobFactory
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
    Object jobInstance = super.createJobInstance(bundle);
    this.beanFactory.autowireBean(jobInstance);
       // Object initializeBean(Object existingBean, String beanName) throws BeansException
    this.beanFactory.initializeBean(jobInstance, null); 
    return jobInstance;
    }
  3. AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
    Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
    if (current == null) {
        return result;
    }
    result = current;
    }
  4. NPE DubboConfigBindingBeanPostProcessor link
78  if (beanName.equals(this.beanName) && bean instanceof AbstractConfig) {
Jeff-Lv commented 6 years ago

Dubbo can fix it by Null checking.

But after navigating the spring code, actually the beanName should be assert Null as spring design, so you'd better update the version of Quartz.

java.lang.IllegalArgumentException: Bean name must not be empty at org.springframework.util.Assert.hasText(Assert.java:169) at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:310) at org.springframework.beans.factory.support.PropertiesBeanDefinitionReader.registerBeanDefinition(PropertiesBeanDefinitionReader.java:468) at org.springframework.beans.factory.support.PropertiesBeanDefinitionReader.registerBeanDefinitions(PropertiesBeanDefinitionReader.java:373) at org.springframework.beans.factory.support.PropertiesBeanDefinitionReader.loadBeanDefinitions(PropertiesBeanDefinitionReader.java:257) at org.springframework.beans.factory.support.PropertiesBeanDefinitionReader.loadBeanDefinitions(PropertiesBeanDefinitionReader.java:221) at sandbox.service.ReportService.getParameters(ReportService.java:89) at sandbox.web.ConfigureReportFormController.formBackingObject(ConfigureReportFormController.java:43) at org.springframework.web.servlet.mvc.AbstractFormController.getErrorsForNewForm(AbstractFormController.java:341) at org.springframework.web.servlet.mvc.AbstractFormController.showNewForm(AbstractFormController.java:322) at org.springframework.web.servlet.mvc.AbstractFormController.handleRequestInternal(AbstractFormController.java:262) at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153) at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:44) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:723) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:663) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:394) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:348) at javax.servlet.http.HttpServlet.service(HttpServlet.java:689) at javax.servlet.http.HttpServlet.service(HttpServlet.java:802) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107

chenxi-null commented 5 years ago

@Jeff-Lv I don't think updating quartz version can fix this NPE problem, because spring-boot-quartz-autoconfiguration pass the null value to beanName! below is the code:

org.springframework.boot.autoconfigure.quartz.AutowireCapableBeanJobFactory

protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
    Object jobInstance = super.createJobInstance(bundle);
    this.beanFactory.autowireBean(jobInstance);
    this.beanFactory.initializeBean(jobInstance, null); // beanName is null!
    return jobInstance;
}

The spring-boot-starter-quartz is belong to spring project, why they break themself's design principle that you mentioned above? Util the latest version '2.1.6.RELEASE', the beanName is still null.

zhaixiaoxiang commented 5 years ago

@Jeff-Lv, We also encounter this BUG. And I think dubbo should execute null checking for defensive programming.

@beiwei30 @chickenlj How do you think?