Location of tld file in web app? - java

I found tld file is lying under location /webapp/WEB-INF/tld in my project. As per my understanding
tld file should lie directly under WEB-INF. I am not getting how come how tag libraries are resolved from
WEB-INF/tld instead of WEB-INF ?
Hereis the inclusion of tag lib in my jsp
<%# taglib uri="com.myComp.utils.customFunctions" prefix="custfunc"%>
For info i am using Spring MVC. I am not sure if it is doing some magic here.

put tld file in "WEB-INF" folder access using uri start with "WEB-INF/demo.tld"

Related

Create JSP tag without creating new .tag file

I'd like to create a JSP tag that would be used multiple times within a single .jsp file. I don't want to create separate .tag file, but rather place this tag in the same .jsp file. Is this possible?
AFAIK the answer would be no, because as per the custom tags documentation, in order to create and use a custom tag in JSP we should be having valid tag library descriptor file in order to define the custom tags and a Tag Handler Class in order to define what action should be performed when we use the custom tag in the JSP file.
Custom Tag was brought in to eliminate the need of the scriptlet tag inside JSP, separation of business logic from JSP so that it would be really easy to maintain and finally re-usability. Custom tags are an excellent way to abstract the complexity of business logic from the presentation of Web pages in a way that is easy for the Web author to use and control.
Moreover, there is one more important condition to render a Custom Tag: A Tag Library Descriptor.
A Tag Library Descriptor is an XML document that contains information about a library as a whole and about each tag contained in the library. TLDs are used by the web container to validate the tags and also by JSP page development tools.
Tag library descriptor file must have the extension .tld and must be packaged in the /WEB-INF/ directory or subdirectory of the WAR file or in the /META-INF/ directory or subdirectory of a tag library packaged in a JAR. The container will take the file as Tag Descriptor fil only if its in tld format and it is packaged as part of WEB-INF directory. If a tag is implemented as a tag file and is packaged in /WEB-INF/tags/ or a subdirectory, a TLD will be generated automatically by the web container.
But there is another small approach to just avoid defining the tag lib as part of your application , you can just define the taglib in JSP and use it without having a tag library as part of your application. For example, lets assume there is a website called "www.example.com" and they have hosted a customlib as part of the application. In that case, you can use the custom lib directly in your JSP. Here below is a small Snipper which could demonstrate the same.
<%# taglib uri = "http://www.example.com/custlib" prefix = "mytag" %>
<html>
<body>
<mytag:hello/>
</body>
</html>
and here is a jsp directive equivalent for the same :
<jsp:directive.taglib uri = "http://www.example.com/custlib" prefix = "mytag" />
References and Sources :
https://docs.oracle.com/javaee/5/tutorial/doc/bnamu.html
https://www.studytonight.com/jsp/creating-a-custom-tag.php
https://www.tutorialspoint.com/jsp/taglib_directive.htm
You can read or check Oracle library about Sharing Tag Libraries Across Web Applications
7.5 Sharing Tag Libraries Across Web Applications
The following sections discuss the packaging, placement, and access of tag libraries and their TLD files:
Packaging Multiple Tag Libraries and TLD Files in a JAR File
Specifying Well-Known Tag Library Locations
Enabling the TLD Caching Feature
7.5.1 Packaging Multiple Tag Libraries and TLD Files in a JAR File
The JSP specification allows the packaging of multiple tag libraries, and the TLD files that define them, in a single JAR file.
This section presents an example of multiple tag libraries packaged in a single JAR file. The JAR file includes tag handler classes, tag-library-validator (TLV) classes, and TLD files for multiple libraries.
The following lists the contents and structure of the JAR file. Note that in a JAR file with multiple TLD files, the TLD files must be located under the /META-INF directory or a subdirectory.
examples/BasicTagParent.class
examples/ExampleLoopTag.class
examples/BasicTagChild.class
examples/BasicTagTLV.class
examples/TagElemFilter.class
examples/TagFilter.class
examples/XMLViewTag.class
examples/XMLViewTagTLV.class
META-INF/xmlview.tld
META-INF/exampletag.tld
META-INF/basic.tld
META-INF/MANIFEST.MF
A JAR file with multiple TLD files must be placed in the /WEB-INF/lib directory or in an OC4J "well-known" tag library location as described in "Specifying Well-Known Tag Library Locations". During translation, the JSP container searches these two locations for JAR files, searches each JAR file for TLD files, and accesses each TLD file to find its <uri> element.
7.5.1.1 Key TLD File Entries
In each TLD file, there is a <uri> element under the root <taglib> element. Use this feature as follows:
The <uri> element must specify a value that is to be matched by the uri setting of a taglib directive in any JSP page that wants to use the corresponding tag library.
To avoid unintended results, each <uri> value should be unique across all <uri> values in all TLD files on the server.
The value of the <uri> element can be arbitrary; however, it must follow the XML namespace convention.I t is simply used as a key and does not indicate a physical location. By convention, however, its value is of the form of a physical location.
The basic.tld file includes the following:
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>basic</short-name>
<uri>http://xmlns.oracle.com/j2ee/jsp/tld/demos/basic.tld</uri>
...
</taglib>
The exampletag.tld file includes the following:
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>example</short-name>
<uri>http://xmlns.oracle.com/j2ee/jsp/tld/demos/exampletag.tld</uri>
...
</taglib>
The xmlview.tld file includes the following:
<taglib>
...
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>demo</short-name>
<uri>http://xmlns.oracle.com/j2ee/jsp/tld/demos/xmlview.tld</uri>
...
</taglib>
7.5.1.2 Key web.xml Deployment Descriptor Entries
This section shows the elements of the web.xml deployment descriptor. These map the full URI values, as seen in the elements of the TLD files in the previous section, to shortcut URI values used in the JSP pages that access these libraries.
The <taglib> element can include two subelements:
<taglib-uri>
Contains the shortcut URI that will be used as the value of the uri attribute in the taglib directive in JSP pages that use the tag.
<taglib-location>
Contains the unique identifier for the tag library. In this case, the value actually indicates a key, not a location, and corresponds to the value in the TLD file of the desired tag library.
For the scenario of an individual TLD file, or the scenario of a JAR file that contains a single tag library and its TLD file, the subelement indicates the application-relative physical location (by starting with "/") of the TLD file or tag library JAR file. See "Specifying Well-Known Tag Library Locations" for related information.
For the scenario of a JAR file that contains multiple tag libraries and their TLD files, a subelement indicates the unique identifier of a tag library. In this case, the value actually indicates a key, not a location, and corresponds to the value in the TLD file of the desired tag library. See "Packaging Multiple Tag Libraries and TLD Files in a JAR File" for related information.
<taglib>
<taglib-uri>/oraloop</taglib-uri>
<taglib-location>http://xmlns.oracle.com/j2ee/jsp/tld/demos/exampletag.tld
</taglib-location>
</taglib>
<taglib>
<taglib-uri>/orabasic</taglib-uri>
<taglib-location>
http://xmlns.oracle.com/j2ee/jsp/tld/demos/basic.tld
</taglib-location>
</taglib>
<taglib>
<taglib-uri>/oraxmlview</taglib-uri>
<taglib-location>
http://xmlns.oracle.com/j2ee/jsp/tld/demos/xmlview.tld
</taglib-location>
</taglib>
7.5.1.3 JSP Page taglib Directives for Multiple-Library Example
This section shows the appropriate taglib directives, which reference the shortcut URI values defined in the web.xml elements listed in the preceding section.
The page basic1.jsp includes the following directive:
<%# taglib prefix="basic" uri="/orabasic" %>
The page exampletag.jsp includes the following directive:
<%# taglib prefix="example" uri="/oraloop" %>
The page xmlview.jsp includes the following directive:
<%# taglib prefix="demo" uri="/oraxmlview" %>
7.5.2 Specifying Well-Known Tag Library Locations
As an extension of the standard "well-known URI" functionality described in the JSP specification, OC4J supports the use of one or more directories, known as well-known tag library locations, where you can place tag library JAR files that will be shared across multiple Web applications.
The default well-known tag library location is the ORACLE_HOME/j2ee/home/jsp/lib/taglib/ directory. A tag library installed in this location will be available by default to all Web applications deployed to the OC4J instance.
You can also define additional shared tag library locations, and install tag library JAR files to be shared across applications in these directories. Defining a well-known tag library location is a two-step process:
Define each directory in the jsp-taglib-locations attribute of the of the element in the ORACLE_HOME/j2ee/home/config/global-web-application.xml file. Separate each location with a semicolon.
Add a element for each directory to ORACLE_HOME/j2ee/home/config/application.xml, the configuration file for the default application. Set the path attribute to the directory containing the tag library JAR file.
Full documentary is down the ink below
Sharing Tag Libraries Across Web Applications

Servlet - web.xml vs Java config

I'm migrating an old project from a web.xml approach to a complete Java-style Servlet 3.0 configuration.
But I can't understand how to translate part of the XML configuration in Java code. In particular the next snippet:
<jsp-config>
<taglib>
<taglib-uri>....</taglib-uri>
<taglib-location>....</taglib-location>
</taglib>
</jsp-config>
Any hint would be welcome!
As a secondary, more academic, question: do Servlet 3.0 API offer a full coverage of what you could do with XML, or not?
Stefano,
Since JSP 2.0, there is no need in put <taglib> tag in web.xml. From Head First Servlets and JSP book:
The Container automatically builds a map between TLD files and names, so that when a JSP invokes a tag, the Container knows exactly where to find the TLD that describes the tag.
How? By looking through a specific set of locations where TLDs are allowed to live. When you deploy a web app, as long as you put the TLD in a place the Container will search, the Container will find the TLD and build a map for that tag library.
So, all you have to do is to have a TLD file with the correct URI.
Places to put your TLD file:
Directly inside WEB-INF
Directly inside a sub-directory of WEB-INF
Inside the META-INF directory inside a JAR fi lethat’s inside
WEB-INF/lib
Inside a sub-directory of META-INF inside a JAR fi lethat’s inside
WEB-NF/lib

Issue with uri of custom tag library

I have seen a weird problem while using custom tag libraries.
In one of my jsp pages the relative uri path of the custom tld file is wrong.
Taglib is included in jsp page like below
<%# taglib prefix="aaa" uri="WEB-INF/bbb.tld" %>
Location of bbb.tld is : Stores\WebContent\WEB-INF\bbb.tld
This taglib is included in a parent jsp file, and not there jsp file is imported/included from parent.
My application has several other jsp files, where the same taglib is used with the correct path.
The same code is deployed in multiple test environments. In a few environments the code is throwing an error of "Failed to find resource", which is expected. But the taglib is working fine in most of the environments, instead of wrong path.
Why is there discrepancy in the behavior between different server environments? Does the server automatically look for all tld files if the uri can't be resolved?
I would recommend adding a trailing slash ('/') before WEB-INF. Could you try the following?
<%# taglib prefix="aaa" uri="/WEB-INF/bbb.tld" %>
Hopefully, this will give you consistent results across all you server instances. Also, having your TLD in Stores\WebContent\WEB-INF\bbb.tld seems to be related to be using an IDE (e.g. Eclipse) to develop your application. Once you export your application as an EAR or WAR the path will look more like Stores.war/WEB-INF/bbb.tld

What are files located in *.jar/META-INF/*.*?

I found that c.tld file of jstl-1.2.jar is located in META-INF/*.* inside this jar. How to access these files from code in this jar? Just with getResourceAsStream("/META-INF/c.tld")? Or META-INF has special processing rules?
It's ok to get the content of the c.tld using getResourceAsStream. Just do not change it and write back to the file.
https://stackoverflow.com/a/70253/32090
tld files are related to Tag libraries. These files will specify when you use a tag in JSP, which class to be executed and which method to be executed. You can access TLDs using URI attribute of taglib directive in JSP.
JSTL tutorial on how to use these tag libraries is available at : http://www.roseindia.net/jstl/introduction.shtml

if a JAR is placed on app servers's classpath how do we reference it from JSP

On our application we are getting an error saying:
PWC6117: File "/struts-tags" not found
code in the file thats giving error is:
<%# taglib prefix="s" uri="/struts-tags" %>
This file is in struts2-core.jar which is placed on the classpath of the app server (Sun 9.1).
The code will work fine and not complain when the jar is actually in WEB-INF/lib of the application, compared to being on classpath of the appserver. But we can not change that. it has to be on appservers classpath.
But how should we change our code so that this error goes away?
I can create mapping in my web.xml so that tag uri's are change. but what should taglib-location be changed to? so that it references to app servers classpath?
<taglib>
<taglib-uri>/WEB-INF/struts-tags.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-tags.tld</taglib-location>
</taglib>
It could be that the app server, and the web application itself are running two different classloaders. So make sure that the jar file is available not just in the app server's classpath, but in the classpath of the application itself. If there is a "shared" lib directory (thats where it would be in WebSphere... not sure about Sun) put it there
The JSP standard does not require an app server to use classpath to locate/load tag librariy tld files. This is just an option available for app servers to store common TLDs. However, the container will use the classpath to locate the class files associated with the tag library. But as a starting step, it must first locate and load the tld file; for this purpose, pretend the classpath doesn't exist.
According to the JSP 2.2 standard, a JSP container maps the URI used in the taglib directive into a Tag Library Descriptor in two steps:
It resolves the URI into a TLD resource [URL] path (a context relative URL path, starting with "/", without protocol or host - i.e. relative to the base URL of the webapp).
This mapping occurs though a taglib map, built from (in order of priority):
A) Java EE platform tag library mappings (JSP Tag Library & JSF libraries)
B) Taglib Map in web.xml
C) Implicit Map Entries from TLDs in WEB-INF/lib/.jar, WEB-INF/.tld & WEB-INF/*/.tld
D) Implicit Map Entries from the Container
E) A fallback, targetted to casual development use, where URI is interpreted as a direct path to the TLD.
Here B) or D) could be useful to you. But D) is an optional priority extension mechanism available to the container, where it inserts mappings of taglibs that the container implements/provides. Reading SUN 9.1 doc, it seems it does not provide D). So, if SUN 9.1 does not detect TLDs in JARs on you classpath, you should use B), as you've started to do in your Q.
It derives the TLD object from the TLD resource path.
The TLD resource path should resolve to:
a TLD file directly,
or to a JAR file that has a TLD file at location META-INF/taglib.tld.
If the TLD resource path is not one of these two cases, a fatal translation error will occur.
Neither of these currently apply to you. So, according to the standard, you either need to extract the jar contents and point <taglib-location> to the resulting TLD file, OR you should insert META-INF/taglib.tld into the JAR file on your class path and point <taglib-location> to the JAR file.
I'm assuming you've already gotten yourself familiar with how TLDs work when placed inside WEB-INF and how the container builds a map to match the uri attributes of JSP taglib directives. So, I'll be more focussed on your classpath problem here.
As per the JSP 2.0 spec
A container looks for TLD files in the following four locations only
/WEB-INF/MyTags.tld
/WEB-INF/Any-Sub-Dir/MyTags.tld
/WEB-INF/lib/tag-lib.jar with /META-INF/MyTags.tld
/WEB-INF/lib/tag-lib.jar with /META-INF/Any-Sub-Dir/MyTags.tld
To not break pre-JSP 2.0 web applications the latest containers would still honour any <taglib> mappings found in web.xml. But, it doesn't help you in any way because the <taglib-location> still remains bound by the locations outlined above. I'm yet to come across any popular container that allows .tlds to be loaded from outside an application's /WEB-INF.
Answer
But, the constraint only applies to the tag library descriptors. The actual tag implementation class just needs to be in the classpath. Usually, the tag classes (along with the tld) are packed within the jar (like struts2-core.jar) and dropped in WEB-INF/lib.
But, they could very well be separate: inside WEB-INF/classes; or, some other jar in WEB-INF/lib or the application server's shared library itself. So, all you need to do is:
Extract just the /META-INF/struts-tags.tld from your struts2-core.jar
Place the struts-tags.tld inside /WEB-INF (/tlds or /struts etc.)
Remove the <taglib> mapping (if running on a JSP 2.0 compliant container)
Some, prefer to keep the mappings just to record the locations of all the tld files being loaded. You could, alternatively, just bundle the /META-INF/struts-tags.tld in a struts2-core-tags.jar and drop it in /WEB-INF/lib.

Categories

Resources