【问题标题】:Tomcat 7 and JSTLTomcat 7 和 JSTL
【发布时间】:2011-08-30 23:04:46
【问题描述】:

我用 Eclipse Tomcat 编写了一个 Web 应用程序,它可以在我的本地 Tomcat 7 上运行,当我尝试在 Tomcat 7 上在线发布它时,出现以下错误:

严重:servlet [obliquid.servlet.Index] 在路径 [/cp] 的上下文中的 Servlet.service() 引发异常 [绝对 uri:http://java.sun.com/jsp/jstl/core 无法在 web.xml 或部署的 jar 文件中解析使用此应用程序]

Tomcat 7 有“规范版本:Servlet 3.0、JSP 2.2、EL 2.2”,所以不包括 JSTL?

当我尝试上传 standard.jar 和 jstl.jar 时出现以下错误:

org.apache.jasper.JasperException: /jsp/index.jsp (line: 3, column: 62) Unable to read TLD "META-INF/c.tld" from JAR file "jndi:/localhost/cp/ WEB-INF/lib/standard.jar": org.apache.jasper.JasperException: 无法加载或实例化 TagLibraryValidator 类:org.apache.taglibs.standard.tlv.JstlCoreTLV

我做了一些谷歌搜索,但我无法解决,有人说这可能是由于 jar 的版本冲突引起的。也许我不应该包含这些 jar 并使用不同的 JSTL url?我的是 JSTL 1.1 我想,有没有 JSTL 1.2 的新 URL?

我应该怎么做才能解决问题并让这个应用程序运行?

【问题讨论】:

  • 嗨 Ravi,我会尝试发布相关部分。与此同时,我继续尝试,而不是使用 rsync 发布(就像我以前一直做的那样),我发布了战争,这一次应用程序工作了。由于它需要保持在线,所以我不会动这台服务器并使用相同的 Tomcat 7.0.14 设置一个新的。我需要几分钟...
  • 查看我们的 JSTL wiki 页面:stackoverflow.com/tags/jstl/info[tag] 悬停在问题下方直到弹出一个框然后单击信息,您可以获得这些页面链接。
  • 感谢 BalusC,总是很有帮助,也许它也应该使用 Servlet 3.0 声明进行更新。 java.sun.com/xml/ns/javaee" xmlns:web="java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xmlns:xsi="w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "java.sun.com/xml/ns/javaeejava.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="Your_Webapp_ID" version="3.0">

标签: java tomcat jstl tomcat7


【解决方案1】:

我已经为此奋斗了几个小时。 这是一个完整的解决方案。

  1. 我使用的是 Tomcat 7,它是一个符合 Servlet 3.0 的服务器。

  2. 如果您想使用 Servlet 3.0 规范,您的 web.xml 必须如下:

    <web-app 
      xmlns="http://java.sun.com/xml/ns/javaee" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> 
    
  3. 如果你使用 Maven,你的 pom.xml 应该有这些行。

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>
    
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    
    <dependency>
        <groupId>org.glassfish.web</groupId>
        <artifactId>jstl-impl</artifactId>
        <version>1.2</version>
        <exclusions>
            <exclusion>
                <artifactId>servlet-api</artifactId>
                <groupId>javax.servlet</groupId>
            </exclusion>
            <exclusion>
                <artifactId>jsp-api</artifactId>
                <groupId>javax.servlet.jsp</groupId>
            </exclusion>
            <exclusion>
                <artifactId>jstl-api</artifactId>
                <groupId>javax.servlet.jsp.jstl</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    

    这些依赖关系非常重要。 JSTL 2.1 + Tomcat 7 + Servlet 3.0 非常损坏,除非您使用这些行来修复它,尤其是排除部分。发生的事情是 JSTL 2.1 Jars 实际上引入了错误版本的 Servlet 规范--2.5。除非你阻止这种情况发生,否则你将陷入痛苦的整个世界。特别感谢Mr. Murray Todd Williams for these insights

  4. 最后,如果 Maven 找不到这些 JARS,您可以通过在您的项目中包含三个 JARS 并执行通常的 Project--> Properties--> Java Build Path 并以这种方式包含它们来让 Eclipse 满意——尽管Maven 应该会处理它。

    javax.servlet-api-3.0.1.jar
    javax.servlet.jsp.jstl-1.2.1.jar
    javax.servlet.jsp.jstl-api-1.2.1.jar
    
  5. 请注意!仅当您使用以下神奇组合时,此确切配置才适用:

    1. 兼容 Servlet 3.0 的应用服务器,例如 Tomcat 7

    2. 您的 web.xml 具有适合 Servlet 3.0 规范的命名空间

    3. 您的类路径中有这三个 JARS,但没有其他 JSTL 或 Servlet JARS。

  6. 确保不要将这些 JAR 的副本放在 WEB-INF/lib 目录中,因为在这种情况下它们会被发送到服务器,从而导致 LinkageErrors。

  7. 在你的 JSP 中,你需要有这个 PRECISE 行,格式与我的完全一样,否则 Eclipse 会抱怨它无法识别 c:blah 标签:

    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    
  8. 多么危险的 PITA!这比任何其他版本的 JSTL 都更难实现。这是唯一一个在以后的迭代中变得更加复杂而不是简单的例子。

【讨论】:

  • 谢谢!我遇到了同样的问题......它浪费了我一天的时间,谢谢你让大家知道!
  • 如果有人觉得解决方案对他们不起作用,请检查 EL 是否被忽略。将以下行添加到您的 JSP 页面。这需要注意不要忽略 EL。
  • 非常感谢。最佳答案,特别感谢 Maven 配置。我已经修改它以与 3.1.0 servlet 一起使用,它的工作就像一个魅力
【解决方案2】:

Tomcat 从未包含 JSTL。

您应该将 jstl 和标准 jar 放入 WEB-INF/lib(您已经这样做了),并确保您有读取它们的权限 (chmod)

你的 URI 是正确的,它应该可以工作(在这里工作)

【讨论】:

  • "Tomcat 从未包含 JSTL":谢谢,我以为新的 Tomcat 7 有它,很高兴知道。可能是权限问题,现在我重新安装,我会检查,我会更新你,谢谢。
  • 好的,这是更新:我在新服务器中安装了所有内容,并且一切正常。不同之处在于我之前以 root 用户 rsync,现在我以 tomcat rsync。我认为这应该意味着它确实是一个权限问题。
【解决方案3】:

您的 uri 对于 JSTL 1.2 是正确的。你需要做两件事:

更改您的web.xml 以使用最新的网络应用版本。

它应该看起来像这样或更高版本;

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    version="3.0">

其次,将正确版本的 jstl jar 放入您的代码中。对于 1.2 您可以下载它们here

这应该给你两个罐子:

  • jstl-api.jar
  • jstl-impl.jar

使用这些,而不是以前版本的 standard.jarjstl.jar

让我们知道这对您有什么作用。

【讨论】:

    【解决方案4】:

    对于在 apache tomcat 7 上运行,将这些添加到您的 POM 中可能是合适的。这些 jar 不像 glassfish 那样引用 javax.servlet jar,因此不需要排除。

    <dependency>
        <groupId>org.apache.taglibs</groupId>
        <artifactId>taglibs-standard-spec</artifactId>
        <version>1.2.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.taglibs</groupId>
        <artifactId>taglibs-standard-impl</artifactId>
        <version>1.2.1</version>
    </dependency>
    

    【讨论】:

      【解决方案5】:

      对于 Tomcat,JSTL 1.1.2 有一个更简单的依赖解决方案:

      <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>jstl</artifactId>
          <!-- Apache Taglibs does not implement version 1.2 -->
          <version>1.1.2</version>
        </dependency>
        <dependency>
          <groupId>taglibs</groupId>
          <artifactId>standard</artifactId>
          <version>1.1.2</version>
          </dependency>
        <dependency>
          <groupId>taglibs</groupId>
          <artifactId>c</artifactId>
          <version>1.1.2</version>
          <type>tld</type>
        </dependency>
        <dependency>
          <groupId>taglibs</groupId>
          <artifactId>fmt</artifactId>
          <version>1.1.2</version>
          <type>tld</type>
        </dependency>
      <dependency>
      

      更多详情请参见here(个人博客)。

      REM: 根据要求提供更多详细信息,必须包含 JSTL 依赖项才能使它们在 Tomcat 上可用。然而,1.2 版并不是必需的,因为 1.1.2 版(由 Apache 提供,如 Tomcat)也可以完成这项工作。它唯一的要求是Servlet 2.4和JSP 2.2,OP提到Servlet 3.0和JSP 2.0就够了。

      【讨论】:

      • 您是否考虑编辑您的答案,使其包含对您的代码的解释,以及为什么/如何回答手头的问题?
      • 我认为这对于那些在 Tomcat 上使用 JSP/JSTL 的人来说是不言自明的。这组依赖也有效。
      【解决方案6】:

      这里有两个答案,关于在处理这个问题时使用 Maven 时如何解决这个问题,大部分是正确的。但是,两者都不是 100% 完成的。

      使用每个 @Tom Hunter's answer 的排除项

      这个答案有效。但是,仍然会有来自 Tomcat 的有关重复 TLD 定义的日志消息。这是因为 jstl 和 jstl-impl 工件都包含 TLD 定义。要删除这些消息,我认为更好的 Maven 设置是这样的:

      <dependency>
          <version>1.2</version>
          <scope>runtime</scope>
          <groupId>javax.servlet.jsp.jstl</groupId>
          <artifactId>jstl-api</artifactId>
          <exclusions>
              <exclusion>
                  <artifactId>servlet-api</artifactId>
                  <groupId>javax.servlet</groupId>
              </exclusion>
              <exclusion>
                  <artifactId>jsp-api</artifactId>
                  <groupId>javax.servlet.jsp</groupId>
              </exclusion>
          </exclusions>
      </dependency>
      
      <dependency>
          <groupId>org.glassfish.web</groupId>
          <artifactId>jstl-impl</artifactId>
          <version>1.2</version>
          <scope>runtime</scope>
          <exclusions>
              <exclusion>
                  <artifactId>servlet-api</artifactId>
                  <groupId>javax.servlet</groupId>
              </exclusion>
              <exclusion>
                  <artifactId>jsp-api</artifactId>
                  <groupId>javax.servlet.jsp</groupId>
              </exclusion>
              <exclusion>
                  <artifactId>jstl-api</artifactId>
                  <groupId>javax.servlet.jsp.jstl</groupId>
              </exclusion>
          </exclusions>
      </dependency>
      

      这仅包括带有必要排除项的 jstl api 类,以避免在该答案的其余部分中解释的问题。

      根据 @George's answer 使用更新的 POM 版本

      我花了一段时间才意识到这一点,但是有更新版本的 JSTL pom 可用。这真的很令人困惑,因为这些较新的包使用相似但略有不同的命名约定。这些较新的版本将 javax.servlet、javax.jsp 等依赖项标记为提供的范围,因此不需要排除它们。 1.2.1 版本依赖于 1.2.1 版本的 jstl-api。所以这个和上面的答案一样有效:

      <dependency>
          <groupId>org.glassfish.web</groupId>
          <artifactId>javax.servlet.jsp.jstl</artifactId>
          <version>1.2.1</version>
          <scope>runtime</scope>
      </dependency>
      

      这与乔治的回答略有不同,因为我将范围更改为运行时。 George 指定了所提供的范围。使用提供的范围,必须手动将 jar 复制到 Tomcat lib 目录中,否则必须包含一些其他依赖项。

      但是,我在 maven Central、jboss 存储库或任何其他存储库中找不到 impl 的 1.2.1 版本。我最终转了一圈,最后只使用了一个基于本地文件的 repo 来存储 jar。这里描述了依赖和jar:

      【讨论】:

        【解决方案7】:

        这些都不适合我,我只是创建了项目而不使用 Maven 并直接添加 JAR 文件。

        【讨论】:

          【解决方案8】:

          我遇到了错误:严重:Servlet.service() for servlet [obliquid.servlet.Index] in context with path [/cp] throw exception [The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolve in both web. Tomcat 7 上的 xml 或随此应用程序部署的 jar 文件]

          解决方案: 将 jars jstl-1.2.jar 和 javax.servlet.jsp.jstl-api-1.2.1.jar 直接复制到 Tomcat 库目录。再次在 Eclipse 中重新部署 Tomcat 库。

          【讨论】:

            【解决方案9】:

            pom.xml 中的以下依赖项似乎可以解决问题:

            <dependency>
                <groupId>org.glassfish.web</groupId>
                <artifactId>javax.servlet.jsp.jstl</artifactId>
                <version>1.2.1</version>
                <scope>provided</scope>
            </dependency>
            
            <dependency>
                <groupId>javax.servlet.jsp.jstl</groupId>
                <artifactId>javax.servlet.jsp.jstl-api</artifactId>
                <version>1.2.1</version>
                <scope>provided</scope>
            </dependency>
            

            这是一个奇怪的组合 - 两个不同的 groupId - 但它确实有效:)。我的期望是看到两个 jar 的相同组 ID。我设法毫无问题地重新部署到 Tomcat 7。

            此外,如果您看到“未知标签

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-01-31
              • 1970-01-01
              • 1970-01-01
              • 2012-02-16
              • 2013-04-07
              • 2012-05-22
              • 1970-01-01
              • 2010-12-04
              相关资源
              最近更新 更多