Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hot reload using undertow application server throws NPE #223

Open
4 tasks done
xqliu opened this issue Oct 5, 2021 · 2 comments
Open
4 tasks done

hot reload using undertow application server throws NPE #223

xqliu opened this issue Oct 5, 2021 · 2 comments

Comments

@xqliu
Copy link
Contributor

xqliu commented Oct 5, 2021

Thanks for reporting an issue for the grails audit-logging plugin.
Please review the task list below before submitting the issue.

WARNING: Your issue report may be closed if the issue report is incomplete and does not include an example. Make sure the below tasks are completed!

NOTE: If you are unsure about something and the issue is more of a question, a better place to ask questions is on Stack Overflow (http://stackoverflow.com/tags/grails) or Slack (http://slack-signup.grails.org). DO NOT use the issue tracker to ask questions.

Task List

  • Steps to reproduce provided
  • Stacktrace (if present) provided
  • Example that reproduces the problem uploaded to Github
  • Full description of the issue provided (see below)

Steps to Reproduce

  1. Generate a new template project on http://start.grails.org/ with web profile
  2. Change the build.gradle file and replace tomcat with undertow as below
// Configuration part 
configurations {
    developmentOnly
    runtimeClasspath {
        extendsFrom developmentOnly
    }
   // @@ --> Follow two lines exclude tomcat packages
    compile.exclude module: 'spring-boot-starter-tomcat'
    compile.exclude group: 'org.apache.tomcat'    
}

// Include undertow explicitly and comment out tomcat part
dependencies {
    developmentOnly("org.springframework.boot:spring-boot-devtools")
    compile "org.springframework.boot:spring-boot-starter-logging"
    compile "org.springframework.boot:spring-boot-autoconfigure"
    compile "org.grails:grails-core"
    compile "org.springframework.boot:spring-boot-starter-actuator"
    compile 'org.grails.plugins:audit-logging:4.0.3'    
    //@@ --> Follow two lines Include undertow explicitly and comment out tomcat part
    //compile "org.springframework.boot:spring-boot-starter-tomcat"
    compile "org.springframework.boot:spring-boot-starter-undertow"    
  1. Configure audit plugin and start the application by grardle bootRun (can directly clone the repo I mentioned below)
  2. Change Application.groovy and add a new line
  3. Reload starts but failed and here are the exception
java.lang.NullPointerException: null
	at io.undertow.servlet.spec.ServletContextImpl.getInitParameterNames(ServletContextImpl.java:430)
	at org.springframework.web.context.support.ServletContextPropertySource.getPropertyNames(ServletContextPropertySource.java:41)
	at org.grails.config.EnvironmentAwarePropertySource.initialize(EnvironmentAwarePropertySource.java:79)
	at org.grails.config.EnvironmentAwarePropertySource.getPropertyNames(EnvironmentAwarePropertySource.java:45)
	at org.grails.config.PropertySourcesConfig.mergeEnumerablePropertySource(PropertySourcesConfig.java:109)
	at org.grails.config.PropertySourcesConfig.initializeFromPropertySources(PropertySourcesConfig.java:98)
	at org.grails.config.PropertySourcesConfig.<init>(PropertySourcesConfig.java:48)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
	at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:80)
	at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:249)
	at grails.plugins.orm.auditable.ReflectionUtils.setAuditConfig(ReflectionUtils.groovy:74)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
	at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2754)
	at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:3809)
	at org.codehaus.groovy.runtime.InvokerHelper.setProperty(InvokerHelper.java:215)
	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setProperty(ScriptBytecodeAdapter.java:496)
	at grails.plugins.orm.auditable.AuditLoggingConfigUtils.mergeConfig(AuditLoggingConfigUtils.groovy:103)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101)
	at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite$StaticMetaMethodSiteNoUnwrapNoCoerce.invoke(StaticMetaMethodSite.java:149)
	at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.callStatic(StaticMetaMethodSite.java:100)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:216)
	at grails.plugins.orm.auditable.AuditLoggingConfigUtils.reloadAuditConfig(AuditLoggingConfigUtils.groovy:71)
	at grails.plugins.orm.auditable.AuditLoggingConfigUtils$reloadAuditConfig$0.call(Unknown Source)
	at grails.plugins.orm.auditable.AuditLoggingGrailsPlugin$_doWithSpring_closure2.doCall(AuditLoggingGrailsPlugin.groovy:110)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:263)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041)
	at groovy.lang.Closure.call(Closure.java:405)
	at groovy.lang.Closure.call(Closure.java:399)
	at grails.spring.BeanBuilder.invokeBeanDefiningClosure(BeanBuilder.java:759)
	at grails.spring.BeanBuilder.beans(BeanBuilder.java:588)
	at grails.spring.BeanBuilder.invokeMethod(BeanBuilder.java:531)
	at org.grails.plugins.DefaultGrailsPlugin.doWithRuntimeConfiguration(DefaultGrailsPlugin.java:543)
	at org.grails.plugins.AbstractGrailsPluginManager.doRuntimeConfiguration(AbstractGrailsPluginManager.java:166)
	at grails.boot.config.GrailsApplicationPostProcessor.postProcessBeanDefinitionRegistry(GrailsApplicationPostProcessor.groovy:171)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:125)
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:706)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
	at grails.boot.GrailsApp.run(GrailsApp.groovy:99)
	at grails.boot.GrailsApp.run(GrailsApp.groovy:485)
	at grails.boot.GrailsApp.run(GrailsApp.groovy:472)
	at myapp.Application.main(Application.groovy:12)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)

Expected Behaviour

Hot reload should success

Actual Behaviour

Hot reload fails and application stops response to frontend request

Environment Information

  • Operating System: MacoS 11
  • GORM Version: 7.0.8.RELEASE
  • Grails Version (if using Grails): 4.0.12
  • JDK Version: 11

Example Application

https://github.com/xqliu/grails-audit-plugin-issue-reproduce

@xqliu
Copy link
Contributor Author

xqliu commented Oct 5, 2021

I have debugged the application and it is caused by deploymentInfo in file io.undertow.servlet.spec.ServletContextImpl is null, when springboot-dev-tools restart the application, the deploymentInfo was first set to null in destroy() method of io.undertow.servlet.spec.ServletContextImpl, but never been set a new value, so NPE error was thrown in below code

 @Override
    public Enumeration<String> getInitParameterNames() {
        return new IteratorEnumeration<>(deploymentInfo.getInitParameters().keySet().iterator());
                                                                 //deploymentInfo is null
    }

The error was caused by the follow line in auditable/ReflectionUtils.groovy

    static void setAuditConfig(ConfigObject c) {
        ConfigObject config = new ConfigObject()
        config.grails.plugin.auditLog = c

        PropertySource propertySource = new MapPropertySource('AuditConfig', [:] << config)
        def propertySources = application.mainContext.environment.propertySources
        propertySources.addFirst propertySource

        // Follow line caused the exception mentioned above
        getApplication().config = new PropertySourcesConfig(propertySources)
    }

Hope the analysis helps.

Thanks.

@xqliu xqliu changed the title Can not hot reload using undertow application serverr hot reload using undertow application server throws NPE Oct 5, 2021
@xqliu
Copy link
Contributor Author

xqliu commented Oct 20, 2021

Hi, is there any update on this or anything I could do to help? Thanks ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant