grails-audit-logging-plugin
grails-audit-logging-plugin copied to clipboard
hot reload using undertow application server throws NPE
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
- [x] Steps to reproduce provided
- [x] Stacktrace (if present) provided
- [x] Example that reproduces the problem uploaded to Github
- [x] Full description of the issue provided (see below)
Steps to Reproduce
- Generate a new template project on http://start.grails.org/ with web profile
- 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"
- Configure audit plugin and start the application by
grardle bootRun
(can directly clone the repo I mentioned below) - Change Application.groovy and add a new line
- 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
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.
Hi, is there any update on this or anything I could do to help? Thanks ;)