如果 JAR 放置在应用程序服务器的类路径上,我们如何从 JSP 引用它
在我们的应用程序上,我们收到一条错误消息:
PWC6117: File "/struts-tags" not found
文件中的代码给出错误是:
<%@ taglib prefix="s" uri="/struts-tags" %>
此文件位于 struts2-core.jar 中,该文件位于应用程序服务器的类路径上(Sun 9.1)。
与位于应用程序服务器的类路径上相比,当 jar 实际上位于应用程序的 WEB-INF/lib 中时,代码将正常工作并且不会抱怨。但我们无法改变这一点。它必须位于应用程序服务器类路径上。
但是我们应该如何更改代码才能消除此错误呢?
我可以在 web.xml 中创建映射,以便更改标签 uri。但是 taglib-location 应该更改为什么呢?以便它引用应用程序服务器类路径?
<taglib>
<taglib-uri>/WEB-INF/struts-tags.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-tags.tld</taglib-location>
</taglib>
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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
应用程序服务器和 Web 应用程序本身可能正在运行两个不同的类加载器。因此,请确保 jar 文件不仅在应用程序服务器的类路径中可用,而且在应用程序本身的类路径中可用。如果有一个“共享”lib 目录(这就是 WebSphere 中的位置...不确定 Sun 的情况),将其放在那里
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
JSP 标准不要求应用服务器使用classpath 来定位/加载标记库tld 文件。这只是应用程序服务器存储常见 TLD 的一个选项。但是,容器将使用类路径来定位与标记库关联的类文件。但作为开始步骤,它必须首先找到并加载 tld 文件;为此,假设类路径不存在。
根据 JSP 2.2 标准,JSP 容器分两步将 taglib 指令中使用的 URI 映射到标签库描述符:
它将 URI 解析为 TLD 资源 [URL ] 路径(上下文相对 URL 路径,以“/”开头,没有协议或主机 - 即相对于 Web 应用程序的基本 URL)。
此映射通过标签库映射进行,构建自(按优先级顺序):
这里的 B) 或 D) 可能对您有用。但 D) 是容器可用的可选优先级扩展机制,它插入容器实现/提供的标记库的映射。阅读SUN 9.1 doc,似乎没有提供D)。因此,如果 SUN 9.1 没有在您的类路径上的 JAR 中检测到 TLD,您应该使用 B),就像您在 Q 中开始做的那样。
它从 TLD 派生 TLD 对象资源路径。
TLD 资源路径应解析为:
如果 TLD 资源路径不是这两种情况之一,则会发生致命翻译错误。
目前这些都不适用于您。因此,根据标准,您要么需要提取 jar 内容并将
指向生成的 TLD 文件,或者您应该插入META-INF/taglib.tld
插入类路径上的 JAR 文件,并将
指向 JAR 文件.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):
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:
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 insertMETA-INF/taglib.tld
into the JAR file on your class path and point<taglib-location>
to the JAR file.我假设您已经熟悉 TLD 放置在
WEB-INF
中时如何工作,以及容器如何构建映射以匹配 JSPuri
属性< code>taglib 指令。因此,我将在这里更加关注您的classpath
问题。根据 JSP 2.0 规范,
容器仅在以下四个位置查找 TLD 文件
为了不破坏 pre- JSP 2.0 Web 应用程序最新的容器仍将支持在
web.xml
中找到的任何
映射。但是,它对您没有任何帮助,因为
仍然受上述位置的约束。我还没有遇到过任何允许从应用程序的/WEB-INF
外部加载.tld
的流行容器。回答
但是,该约束仅适用于标签库描述符。实际的标签实现类只需位于
classpath
中。通常,标签类(以及tld
)打包在 jar 中(如struts2-core.jar
)并放入WEB-INF/lib< /代码>。
但是,它们很可能是分开的:在 WEB-INF/classes 内;或者,
WEB-INF/lib
中的其他 jar 或应用程序服务器的共享库本身。因此,您需要做的就是:struts2-core.jar
中提取/META-INF/struts-tags.tld
struts-
(/WEB-INF
内的 tag.tld/tlds
或/struts
等);
映射(如果在 JSP 2.0 兼容容器上运行)有些人更喜欢保留映射,只是为了记录正在加载的所有
tld
文件的位置。或者,您也可以将/META-INF/struts-tags.tld
捆绑在struts2-core-tags.jar
中,然后将其放入/WEB -INF/lib
.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 theuri
attributes of JSPtaglib
directives. So, I'll be more focussed on yourclasspath
problem here.As per the JSP 2.0 spec
A container looks for TLD files in the following four locations only
To not break pre-JSP 2.0 web applications the latest containers would still honour any
<taglib>
mappings found inweb.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.tld
s 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 thetld
) are packed within the jar (likestruts2-core.jar
) and dropped inWEB-INF/lib
.But, they could very well be separate: inside
WEB-INF/classes
; or, some other jar inWEB-INF/lib
or the application server's shared library itself. So, all you need to do is:/META-INF/struts-tags.tld
from yourstruts2-core.jar
struts-tags.tld
inside/WEB-INF
(/tlds
or/struts
etc.)<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 astruts2-core-tags.jar
and drop it in/WEB-INF/lib
.