Why are certain tasks being invoked unexpectidly?


(dmolineu) #1

I’m working on setting up a continuous integration system using Gradle for the first time. The issue I’m having is that I sort of have two paths that a build should follow, depending on how it is invoked. It should either copy the war to D:\wars\front or D:\wars\service and then deploy to one of either our front end web tc server or services server. The deployment part is working as expected, however all wars are being put into both directories.

The basic structure of my build (omitting hopefully irrelevant details) is:

task undeployFromFront (type: Exec) {
 ignoreExitValue = true
 executable EXECUTABLE
 args //omitted
}
   task undeployFromSvc (type: Exec) {
 ignoreExitValue = true
 executable EXECUTABLE
 args //omitted
}
  task deployToFront (type: Exec, dependsOn: undeployFromFront) {
 def frontWarDir = "D:\wars\front"
 copy {
  from war
  into frontWarDir
  include '*.war'
 }
 workingDir CMD_WORKING_DIR
 executable EXECUTABLE
 args //omitted
}
  task deployToSvc (type: Exec, dependsOn: undeployFromSvc) {
 def svcWarDir = "D:\wars\service"
 copy {
  from war
  into svcWarDir
  include '*.war'
 }
 workingDir CMD_WORKING_DIR
 executable EXECUTABLE
 args //omitted
}

From Jenkins each build is calling either “deployToFront” or “deployToSvc” (or just “build” for our nightly build-only jobs). I have a debug statement (not shown above) at the top of the two deploy tasks that echos where the war will be copied, so in my log I see both log statements, indicating that it must be running both deploy tasks. Ironically, it doesn’t appear to be running both undeploy tasks though, just both deploys, bit it isn’t actually deploying to both servers (as it shouldn’t). I tested a build on both sides and they’re each deploying ONLY to the correct server. It’s like the copy command from both deploy jobs is always executed whenever either deploy is called, but only the intended executable command (which actually does the deployment to the server) is ran from that same deploy task.

Hopefully this makes sense. Any help would be much appreciated!


(Peter Niederwieser) #2

One obvious mistake is that the deploy tasks copy files at configuration time, i.e. always and no matter which tasks get executed (and too early). Instead these should be two ‘Copy’ tasks, which the deploy tasks depend on.


(dmolineu) #3

I broke the copy war part out of the deploy tasks and created their own copy tasks:

task stageFrontWar (type: Copy, dependsOn: war) {
 def frontWarDir = "D:\wars\front"
 copy {
  from war
  into frontWarDir
  include '*.war'
 }
}

then added a dependency on the undeploy tasks from the deploy tasks:

task deployToFront (type: Exec, dependsOn: [stageFrontWar, undeployFromFront]) {..}

With these changes everything behaves the same as it did before. When I add << to the deploy (Exec) tasks, I get an error saying:

Caused by: java.lang.IllegalStateException: execCommand == null!

If I instead put << on the stageWar (Copy) tasks I get:

[ERROR] [system.err] Failed to execute command deploy-application. Reason: Cannot find file: D:\wars\front\MyApp.war.

So it looks like it’s trying to copy the war before the war task is complete. Shouldn’t “dependsOn: war” prevent this?


(dmolineu) #4

With these changes everything behaves the same as it did before. When I add “<<” to the deploy (Exec) tasks, I get an error saying:

Caused by: java.lang.IllegalStateException: execCommand == null!

If I instead put “<<” on the stageWar (Copy) tasks I get:

[ERROR] [system.err] Failed to execute command deploy-application. Reason: Cannot find file: D:\wars\front\MyApp.war.

So it looks like it’s trying to copy the war before the war task is complete. Shouldn’t “dependsOn: war” prevent this?


(Peter Niederwieser) #5

That’s making the same mistake. The ‘project.copy’ method and ‘Copy’ task type are two different, alternative ways of copying. ‘project.copy’ must always be used in a task action (e.g. ‘doLast { … }’). A ‘Copy’ task would look as follows:

task stageFrontWar (type: Copy) {
     from war // task dependency inferred automatically
     into "D:\wars\front" // uncommon to use an absolute path
}

(dmolineu) #6

Thanks for the clarification! Removing the project.copy surrounding the “from” and “into” lines in my copy tasks took care of the issue of it copying to both locations!