Hi,
I am trying to add folders to the ‘WEB-INF’ of a WAR archive that is defined in a web services plugin I am trying to wrap up.
The plugin basically just goes in, finds the wsdl file, and then resolves all the schema the wsdl depends on and packages them in the war under two separate base folders.
- ‘WEB-INF/wsdl’ * ‘WEB-INF/schema’
Writing a few plugins in the past I was basically chaining separate tasks together. So my tasks dependency looks like:
getWsdlName << resolveWsdlDependencies << wsdlWar
the ‘resolveWsdlDependencies’ task populate the Extension object with a list of objects that contain the Strings to pass as input to the ‘from’, ‘to’, and ‘include’ arguments to the CopySpec builder.
While the wsdlWar task doesn’t fail, it just doesn’t populate anything in the ‘WEB-INF’ that a regular war wouldn’t do. I know the other tasks are working fine because I have tested them.
The war looks normal:
class WsdlWarTask extends War {
WsdlWarTask() {
super()
}
@TaskAction
def void addDocumentsToWar() {
project.extensions.wsdl.resolved.each { resolvee ->
log.info("from : {}, into : {}, include: {}", resolvee.from, resolvee.into, resolvee.include)
webInf {
from resolvee.from
into
resolvee.into
include resolvee.include
}
}
}
}
I have also tried to get the CopySpec defined in ‘War.groovy’, but no dice.
resolved.each { resolvee ->
log.info("from : {}, into : {}, include: {}", resolvee.from, resolvee.into, resolvee.include)
getWebInf().from (resolvee.from)
{
into
resolvee.into
include resolvee.include
}
}
What DOES work though, and it has a major drawback, is putting the code above, in the constructor. The drawback is that I can’t depend on my other tasks to do the work in the constructor, (I have only been able to chain tasks that have an ‘@TaskAction’ annotation on a method, as it seems that is when the task dependencies are sorted out).
WsdlWarTask() {
super()
def wsdlName = nameConvention.findWsdlFileName(project.name)
def wsdlFile = new File(project.extensions.wsdl.wsdlDirectory, wsdlName + ".wsdl")
dependencyResolver.wsdlFile = wsdlFile
def resolveList = dependencyResolver.resolveWSDLDependencies()
def resolved = resolveList.collect { resolvePaths.resolveRelativePathsToWar(project.rootDir, it) }
resolved.each { resolvee ->
log.info("from : {}, into : {}, include: {}", resolvee.from, resolvee.into, resolvee.include)
getWebInf().from (resolvee.from)
{
into
resolvee.into
include resolvee.include
}
}
}
With this I get my expected war output
drwxr-xr-x
0 20-Jan-2013 21:19:26 WEB-INF/wsdl/
-rw-r–r–
2049 19-Jan-2013 20:56:44 WEB-INF/wsdl/HelloWorldEpisodeBindingService.wsdl
drwxr-xr-x
0 20-Jan-2013 21:19:26 WEB-INF/schema/
drwxr-xr-x
0 20-Jan-2013 21:19:26 WEB-INF/schema/HelloWorld/
-rw-r–r–
581 19-Jan-2013 20:56:44 WEB-INF/schema/HelloWorld/HelloWorld.xsd
There are two things that are a little off. Any subproject that applies this plugin goes through this whole resolution process before anything is even run. Like even the debug output of ‘gradle tasks’ shows all subprojects doing all the processing in the ‘WsdlWarTask()’ constructor, just to show what the tasks are. If I’m not mistaken it even does this on a clean too. (putting the code where I originally wanted it, doesn’t do this however)
I also lose the flexibility of extensions with this method. It only works with the default extension settings (for me, the default wsdl folder is ‘wsdl’). If for some instance, say the wsdl folder was actualy ‘WSDL’ the plugin would crash at ‘apply’ time because it is trying to find the file at wsdl and process it’s contents with XmlSlurper and it can’t find it so it crashes and outputs
TaskInstantiationException: Could not create task of type ‘WsdlWarTask’
and the extension mechanism of
wsdl {
wsdlDirectory = file(new File(project.rootDir, "WSDL"))
}
doesn’t work, because it doesn’t get called as early as the things in the constructor. Or so I think.
I would really like to extend the war with the @TaskAction annotated method creating and populating the folders inside ‘WEB-INF’. Am I doing something wrong, or is there a better way?