问题
I am having really hard time figuring this one out. I have an app which works fine in intellij and as a standalone war (created with gradlew assemble
). But when I am trying to deploy this war (created with gradlew assemble
but with tomcat starter set as provided
in build.gradle file) in the tomcat 8.5, I am getting this exception. But if I generate a war using gradlew war
then I do not see this exception and tomcat is deployed alright. But in that case my app is giving all kind of crap errors on the front end related to gsps and g: namespace.
Caused by: java.lang.NullPointerException
at grails.plugin.springsecurity.web.access.intercept.AnnotationFilterInvocationDefinition.findActionRoles(AnnotationFilterInvocationDefinition.groovy:458)
at grails.plugin.springsecurity.web.access.intercept.AnnotationFilterInvocationDefinition.findAnnotations(AnnotationFilterInvocationDefinition.groovy:425)
at grails.plugin.springsecurity.web.access.intercept.AnnotationFilterInvocationDefinition.findAnnotations(AnnotationFilterInvocationDefinition.groovy)
at grails.plugin.springsecurity.web.access.intercept.AnnotationFilterInvocationDefinition.findControllerAnnotations(AnnotationFilterInvocationDefinition.groovy:382)
at grails.plugin.springsecurity.web.access.intercept.AnnotationFilterInvocationDefinition.initialize(AnnotationFilterInvocationDefinition.groovy:223)
at grails.plugin.springsecurity.web.access.intercept.AnnotationFilterInvocationDefinition$initialize.call(Unknown Source)
at grails.plugin.springsecurity.SpringSecurityCoreGrailsPlugin.initializeFromAnnotations(SpringSecurityCoreGrailsPlugin.groovy:770)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:210)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:59)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166)
at grails.plugin.springsecurity.SpringSecurityCoreGrailsPlugin.doWithApplicationContext(SpringSecurityCoreGrailsPlugin.groovy:651)
at org.grails.plugins.DefaultGrailsPlugin.doWithApplicationContext(DefaultGrailsPlugin.java:523)
at org.grails.plugins.AbstractGrailsPluginManager.doPostProcessing(AbstractGrailsPluginManager.java:224)
at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy:246)
at grails.boot.config.GrailsApplicationPostProcessor.onApplicationEvent(GrailsApplicationPostProcessor.groovy)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:383)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:389)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:337)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:882)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:144)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:545)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:372)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at grails.boot.GrailsApp.run(GrailsApp.groovy:83)
at org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:151)
at org.grails.boot.context.web.GrailsAppServletInitializer.createRootApplicationContext(GrailsAppServletInitializer.groovy:57)
at org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:86)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5205)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
I am really unable to why this is happening ? This is my application.groovy
file (security related configuration)
grails.plugin.springsecurity.userLookup.userDomainClassName = 'my.domain.Person'
grails.plugin.springsecurity.authority.className = 'my.domain.Role'
grails.plugin.springsecurity.securityConfigType = 'Annotation' //"InterceptUrlMap"
grails.plugin.springsecurity.password.algorithm = 'MD5'
grails.plugin.springsecurity.useSecurityEventListener = true
grails.plugin.springsecurity.useSessionFixationPrevention = true
grails.plugin.springsecurity.rejectIfNoRule = true
grails.plugin.springsecurity.fii.rejectPublicInvocations = false // make this true only in dev mode. XXX
/**
* Salting a password is a good strategy from security point of view.
* @see https://grails-plugins.github.io/grails-spring-security-core/v3/#salt
*/
grails.plugin.springsecurity.dao.reflectionSaltSourceProperty = 'username'
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
[pattern: '/', access: ['permitAll']],
[pattern: '/error/**', access: ['permitAll']],
[pattern: '/index', access: ['permitAll']],
[pattern: '/index.gsp', access: ['permitAll']],
[pattern: '/shutdown', access: ['permitAll']],
[pattern: '/assets/**', access: ['permitAll']],
[pattern: '/**/js/**', access: ['permitAll']],
[pattern: '/**/css/**', access: ['permitAll']],
[pattern: '/**/images/**', access: ['permitAll']],
[pattern: '/**/favicon.ico', access: ['permitAll']],
[pattern: '/installrep/**', access: ['permitAll']],
[pattern: '/status/**', access: ['permitAll']],
[pattern: '/upgradeRepository/**', access: ['permitAll']],
[pattern: '/patchUpgradeRepository/**', access: ['permitAll']],
[pattern: '/log/**', access: ['permitAll']],
[pattern: '/help/**', access: ['permitAll']],
[pattern: '/login/**', access: ['permitAll']],
[pattern: '/logout/**', access: ['permitAll']]
]
grails.plugin.springsecurity.filterChain.chainMap = [
[pattern: '/assets*', filters: 'none'],
[pattern: 'js*', filters: 'none'],
[pattern: 'css*', filters: 'none'],
[pattern: 'images*', filters: 'none'],
[pattern: 'favicon.ico', filters: 'none'],
[pattern: '/endpoints*', filters: 'JOINED_FILTERS,-filterInvocationInterceptor'],
[pattern: '/services*', filters: 'JOINED_FILTERS,-filterInvocationInterceptor'],
[pattern: '/**', filters: 'JOINED_FILTERS']
]
Can somebody please help me understand what is going on ?
回答1:
Finally, I tracked down the code. First of all, the difference between grails run-app vs running a war owes it to two implementations of AbstractGrailsApplication class in grails-core. For war, DefaultGrailsApplication is used and for intellij and others, it uses StandaloneGrailsApplication.
And the problem in this case arises out of this function in DefaultGrailsApplication calls.
public GrailsClass getArtefact(String artefactType, String name) {
ArtefactInfo info = getArtefactInfo(artefactType);
return info == null ? null : info.getGrailsClass(name);
}
Apparently the artifact is being looked into cache. In case of tomcat, I had been seeing the warnings as mentioned in this post here. And taking hints from that post, I used this answer and that does solve this issue here for me. I did not try by disabling the cache in tomcat. That probably might help as well. Let me know if you try that option out.
Hope this helps someone. I had been after this for more then a week now.
Update and solution
Move the cfx dependency in gradle file above spring security plugin and then you should see spring security being configured once only. See this question.
来源:https://stackoverflow.com/questions/43594786/gradle-war-vs-gradle-assemble-grails-3-2-6-and-sec-plugin-3-1-2