WAR plugin doesn't include src/main/webapp in classpath

Hi,

I have a very simple webapp. I’m using gradle war plugin. It doesn’t see src/main/webapp in the classpath when running tests, but it does see it when building a WAR for deployment. Also, STS keeps removing src/main/webapp as source folder.

This helps with the former issue: sourceSets.test.runtimeClasspath += files(“src/main/webapp”) but not with the latter. Anyway, I thought src/main/webapp was a fairly standard location? Thanks for any help.

And this is my build.gradle: https://github.com/m1key/audiolicious-cloud/blob/master/build.gradle

Files in ‘src/main/webapp’ will be copied to the root of the War archive. They will not be on the runtime class path of the web app. Hence they aren’t on the runtime class path of the ‘test’ task either. For resources that need to be on the class path, use ‘src/main/resources’ or ‘src/test/resources’.

PS: It shouldn’t be necessary to copy the War file just to change its name. Instead, you should reconfigure the ‘war’ task, for example with ‘war.archiveName = …’.

Hi Peter, thanks for your answer. Well, I need the Spring WEB-INF/blah-servlet.xml file that’s in there (and WEB-INF/web.xml soon). So is the recommended practice to move that to src/main/resources?

I will address the renaming bit separately when we figure this one out. :slight_smile:

‘web.xml’ and Spring’s ‘servlet.xml’ have to be placed directly under ‘WEB-INF/’, so you can’t just move them into ‘src/main/resources’ (which will be placed under ‘WEB-INF/classes’). If you need ‘web.xml’ and ‘servlet.xml’ on the test runtime class path, you can do so explicitly, similar to what you already did.

Thanks again, Peter. If Gradle recognises this folder by default, what is the point of it not being in the classpath?

As per the servlet specification, only ‘WEB-INF/classes’ and ‘WEB-INF/lib/*’ are placed on the web app’s runtime class path. ‘src/main/webapp’ is meant for all other files that need to go into the War. Hence there is no reason for Gradle to put ‘src/main/webapp’ on the test runtime class path.

So you said: “web.xml and Spring’s servlet.xml have to be placed directly under WEB-INF/, so you can’t just move them into src/main/resources” and “[Files from] src/main/webap […] are served statically and aren’t part of the web app’s runtime class path”

Where do I put my web.xml and servlet.xml files then?

I’ve edited and improved my previous post. To answer your question, ‘web.xml’ and ‘servlet.xml’ go into ‘src/main/webapp/WEB-INF’. They can’t (and don’t have to) be loaded by the web app’s class loader.

But having a web.xml file is as standard as it gets with web apps. Why should Gradle force me to put some extra config for my tests to work? It could only load src/main/webapp/WEB-INF into classpath, not the whole src/main/webapp folder.

But having a web.xml file is as standard as it gets with web apps.

Having a web.xml - yes. Having it on the class path - no.

Gradle preconfigures the test runtime class path to match the web app’s runtime class path. If your tests, for whatever reason, need a different class path, you’ll have to let Gradle know. In general, this should be easy.

If you are still left wondering, I encourage you to read the relevant parts of the servlet specification.

Excuse my ignorance, but the Spring servlet.xml file is available to the app during runtime! So Gradle test runtime classpath does not match the runtime one by default. My tests need the exact same classpath.

It is available, but not via the web app’s class loader. The servlet specification has the details.

I see. That’s a bit disappointing. Thanks for your answers!

AD PS. Yeah, that works, thanks.