Stand-alone web applications cannot load classes from jars that are inside other jars. Which is what a WAR technically is, even though Tomcat supports exploded WARs.
By convention, webapp servers can load classes from jars that are in the WEB-INF/lib directory, and Tomcat uses a custom classloader to do just that. However, as Misha said, it looks only in the WEB-INF/lib directory, and not in subdirectories.
Since WEB-INF/lib is really just a repository for JARs in a war, there's not all that much benefit in redefining its behavior. Easier just to dump all the jars into WEB-INF/lib.
An IDE is no substitute for an Intelligent Developer.
Skip Cole wrote:Personally, I am all for organizing things. I think it helps one debug faster and avoid jar hell.
It really is a shame one can't put subdirectories in the WEB-INF/lib folder. I'm just saying ...
Well, like we said, if you want it bad enough, you can create a custom classloader.
However, I have some pretty large webapps and never felt the need myself. Most of my libraries are off-the-shelf Maven products and their naming conventions provide sort of a synthetic "folder" structure as long as you view the directory sorted.
Having sub-folders in WEB-INF/lib directory should be possible without the trouble of going into creating customized class loaders.
It seems that it just make sense. Sometimes there can be so many jar files in there that it looks like a zoo. It looks more organized and clean with having sub-folders. If there are sub-folders then it becomes easier to remove unwanted jar files without risk of breaking the code, it also makes it easier to know what jars are used where. It is very easy to keep on dropping jars in the lib folder but one would have to think twice before removing them because there is a concern that something might get broken. Which bring back to my initial point of having clarity and simplicity.
It would make equal sense for stand-alone application jars to have that capability. But they don't.
I'm afraid that sub-folders in either location wouldn't really provide any safety as far as removal goes. The real discriminator in Java isn't what jar or folder a class it is in, it's what package it's in. You can have parts of the same package in more than one location, and, in fact, J2EE is a pretty good example of that: some of the J2EE classes are in the reference libraries, some are implemented in the server implementation.
When a class is instantiated, the source it came from is immaterial. You can break things just as thoroughly (and mysteriously) no matter if the library was at the root or it was in a sub-directory when you removed it.