|SE looks for TLD files within the structure of the web application as follows (in this order):
Think of a TLD the same as you do a JSP or an image or html file.
Or the web.xml file (probably a better analogy since those are both "descriptors").
Directly under Under WEB-INF or any subfolder under WEB-INF
Inside any JAR file under WEB-INF\lib. Specifically within each JAR in that lib folder it looks for
It needs to be inside the app structure.
This differs from a .class or .properties file which may either be inside the app or on the main classpath.
Confusion may come (for the humans) with the fact that a .jar file may
contain non-classpath items such as a TLD file. The ability to place a TLD inside a JAR and have it be found is to simplify the act of handing someone your TLD-related code. For example the struts JARs include both Tag Handler code *and* their associated TLDs in 1 simple JAR package (keeping related things all in one place). In that case one could place such a JAR on the main SE classpath instead of inside a webapp so that all apps could share it. However each app would need to include its own copy of the TLD files.