Mutlimodel project- War generated with wrong content

Hi,
I’m trying to generate a war from a sub-project, the problem is that I don’t get the correct content at the end. Here’s the situation:
First the project layout looks like this:

  • MainProject
    —subproject-1

    – subproject-X

    —subproject k

Without forget to mention that I have done all the required configuration from mutli-modules build and into the subproject-X I was trying to generate a war file from custom directory generated into the buildDir and where I will in advance adding into it the custom content.

Now coming to war generation task, under “subproject-X/build.gradle”:


task generateWar(type: War){ version "$version" classpath=configurations.compile doLast{ from ("$buildDir/war") destinationDir = file("$buildDir/dist") } }


Finally I don’t get the war file into the desired directory ($“buildDir/dist”) and I don’t get the desired content from ("$buildDir/war").
Thanks.

In the code shown, the configuration of from and destinationDir occurs in a doLast block. The doLast block would cause the configuration of these properties to occur in the execution phase after the task action that creates the war, which is too late. You probably want to set these in the configuration phase by removing the doLast { ... } block around the from and destinationDir configuration.

Hi James,
thanks for replying, removing whether the doLast or << would not be sufficient to solve the problem, here’s is an update for my situation:


task generateWar(type: War){
     version "$version"
     classpath=configurations.compile
     from ("$buildDir/war")
     destinationDir = file("$buildDir/dist")

}


I share with you that destinationDir should not be specified at the execution time, but still the big question mark why I don’t get the right content. I have tried also some other configuration like the below, but always I got a negative result from war or generateWar task:


webAppDirName="$buildDir/war"

Another thing weird when I do like the following:


task generateWar(type: War){
  	version "$version"
  	classpath=configurations.compile
  	//destinationDir = file("$buildDir/dist")
  	doLast{
	from ("$buildDir/war")
	}
}

I manage to get only classes directory into the war file, I have commented the destinationDir so that classes directory may be added. I can figure out how the destinationDir affects the classes addition, because when it’s not commented no classes directory will be copied to war and the war of course will be generated to “$buildDir/lib”.

Is this explained by the fact that I have a conflict with the MainProject or I need to do another settings?

What is your intention with the line above? You mentioned that you are missing some files that you expect in the war. Are you intending to replace all of the default contents, or add to it? If you are intending to add to it, you want:

classpath configurations.compile

The classpath and setClasspath methods have different behavior.

Actually I want to replace all of the default content and create the war only using the “$buildDir/war” content generated by some previous tasks. Anyways speaking of the classpath configuration.compile this accutally my main problem because is related to sourceSets and dependencies. My main concern is that there some files copied during the file and I can figure out how to add it into the War. Let me be more clear:

  • Suppose that I have a copy task which collect all the resources and put them into the “$buildDir/war” directory:

apply plugin:'java'
apply plugin:'eclipse'
apply plugin:'war'
apply from:'gradle/dependencies.gradle'
    // under the suproject-X
    sourceSets{
    	main{
    	output.classesDir=file("$buildDir/war/WEB-INF/classes")
    	}
    	test{
    	output.classesDir=file("$buildDir/war/WEB-INF/classes")
    	}
    }
    
    //copy some files to $buildDir/war
    task collectWarResources<<{
    	copy{
    	from("./WebContent"){include ("**/*")}
    	into("$buildDir/war")
    	}
    	copy{
    	....
    	}
    // generate the War using only the content of the $buildDir/war
    task generateWar(type: War){
      	version "$version"
      	classpath configurations.compile
      	//destinationDir = file("$buildDir/dist")
    	from ("$buildDir/war")
    }

Thanks

Why do you need to have the copy task that collects the resources? The war task is basically a more specialized copy task, so it is possible to collect all of the resources that you need without an additional copy step.

In trying to construct the war file by specifying certain output locations, copying them to a new location, and then copying them into the war, it is fairly easy to miss something. If the first copy task occurs before all files are generated or before the correct location is configured (like the case with doLast initially), you’ll be missing those files in the war.

Rather than trying to sort through the ordering and file output locations manually, I would recommend that you configure the war using the conventions that are provided on each project. This will guarantee that the appropriate task dependencies are set up and you’re not missing anything.

May be I haven’t detailed all the copy task, but sometimes the separation is needed because I have to customize the content of some files (replace some tokens, others generated by external tasks). So this left me we the only solution that requires to collect all the data to temporary location and then using it to generate my custom war.
I have always use this strategy and it works fines for classic projects, but now this is the first time that I’m trying to do this for a multi-module project based.
Well I will keep digging and try to figure out what going on. Once solved may be I will provide a solution.
Thank you again James.

Sorry I’m new user I can’t upload an image.
Anyway the problem was not related to the code. It’s when I decompress the war for checking the content of the war. I highly recommend to do not reply on Eclipse for checking the content of the war (you know you can easily check the war without have to decompress it).
So I have noticed that the content viewed from the Eclipse is completely different from the one in winrar for example.
Anyway don’t let that trap you, here’s the working snipped code:


task generateWar(type: War){
  	version "$version"
  	classpath configurations.compile
  	destinationDir = file("$buildDir/dist")
	from ("$buildDir/war")
}

Finally the lesson that I have learned is to do not rely always on Eclipse to check the war content. Even a refresh of the project won’t lead to a positive result and you will risk to waste your day for nothing.