Details
Description
doWithWebDescriptor takes a GPathResult parameter. GPathResult is intended to be read only but partially supports modification. Consider the following 3 code blocks. There is no way for plugin C to remove elements added by previous plugins. The replaceNode method demonstrated has the side effect of also removing the node added by plugin B.
class AGrailsPlugin {
def doWithWebDescriptor = { xml ->
def mappingElement = xml.'servlet'
mappingElement[mappingElement.size() - 1] + {
'servlet' {
'servlet-name'('a')
'servlet-class'('com.discorp.web.AServlet')
}
}
}
}
class BGrailsPlugin {
def loadAfter = ['a']
def doWithWebDescriptor = { xml ->
def mappingElement = xml.'servlet'
mappingElement[mappingElement.size() - 1] + {
'servlet' {
'servlet-name'('b')
'servlet-class'('com.discorp.web.BServlet')
}
}
}
}
class CGrailsPlugin {
def loadAfter = ['b']
def doWithWebDescriptor = { xml ->
def n = xml.servlet.find { node -> node.'servlet-name'.text() == 'a' }
n.replaceNode {}
}
}
A real-world example is a JBoss plugin I'm working on that needs to remove log4j configuration from web.xml. If the JBoss plugin is loaded after another plugin that modifies web.xml (e.g. AcegiPlugin) those plugins modifications are lost.
Issue Links
- duplicates
-
GRAILS-2977
Cannot insert plugin filter mapping in desired location of web.xml
-
Reduced priority of non critical issues which have current workarounds