webentwicklung-frage-antwort-db.com.de

Tomcat 7 und JSTL

Ich habe mit Eclipse Tomcat eine Webanwendung geschrieben, die auf meinem lokalen Tomcat 7 funktioniert. Als ich versuchte, sie online auf einem Tomcat 7 zu veröffentlichen, trat der folgende Fehler auf:

SEVERE: Servlet.service () für Servlet [obliquid.servlet.Index] im Kontext mit Pfad [/ cp] hat Ausnahme ausgelöst [The absolute uri: http://Java.Sun.com/jsp/jstl/core kann weder in web.xml noch in den mit dieser Anwendung bereitgestellten JAR-Dateien aufgelöst werden]

Tomcat 7 verfügt über "Spec-Versionen: Servlet 3.0, JSP 2.2, EL 2.2", sodass JSTL nicht enthalten ist?

Als ich versuchte, standard.jar und jstl.jar hochzuladen, hatte ich den folgenden Fehler:

org.Apache.jasper.JasperException: /jsp/index.jsp (Zeile: 3, Spalte: 62) TLD "META-INF/c.tld" kann nicht aus der JAR-Datei "jndi:/localhost/cp/WEB-INF" gelesen werden /lib/standard.jar ": org.Apache.jasper.JasperException: Fehler beim Laden oder Instanziieren der TagLibraryValidator-Klasse: org.Apache.taglibs.standard.tlv.JstlCoreTLV

Ich habe ein bisschen gegoogelt, aber ich konnte es nicht klären, einige sagten, es könnte an widersprüchlichen Versionen der Gläser liegen. Vielleicht sollte ich diese Gläser nicht einschließen und eine andere JSTL-URL verwenden? Meins ist für JSTL 1.1 Ich denke, gibt es eine neue URL für JSTL 1.2?

Was soll ich tun, um das Problem zu lösen und diese Anwendung zum Laufen zu bringen?

44
stivlo

Tomcat hat JSTL nie aufgenommen.

Sie sollten die JSTL- und Standard-Gläser in WEB-INF/lib (das hast du getan), und stelle sicher, dass du die Berechtigung hast, sie zu lesen (chmod)

Ihre URI ist korrekt und sollte funktionieren (funktioniert hier)

45
Bozho

Ich habe mehrere Stunden damit gekämpft. Hier ist eine vollständige Lösung.

  1. Ich verwende Tomcat 7, einen Servlet 3.0-kompatiblen Server.

  2. Wenn Sie die Servlet 3.0-Spezifikation verwenden möchten, müssen Sie Ihre web.xml wie folgt haben:

    <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. Wenn Sie Maven verwenden, sollte Ihre pom.xml diese Zeilen haben.

    <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>
    

    Diese Abhängigkeiten sind sehr wichtig. JSTL 2.1 + Tomcat 7 + Servlet 3.0 ist sehr fehlerhaft, es sei denn, Sie beheben es mithilfe dieser Zeilen, insbesondere des Ausschlussteils. Was passiert, ist, dass die JSTL 2.1-Jars tatsächlich die falschen Versionen der Servlet-Spezifikation 2.5 einspielen. Wenn Sie das nicht verhindern, werden Sie in einer Welt voller Schmerzen sein. Ein besonderer Dank geht an Mr. Murray Todd Williams für diese Erkenntnisse .

  4. Falls Maven diese JARS nicht finden kann, können Sie Eclipse glücklich machen, indem Sie drei JARS in Ihr Projekt aufnehmen und das übliche Project -> Properties -> Java Build Path and include) ausführen sie auf diese Weise - obwohl Maven sich darum kümmern sollte.

    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. Bitte beachten Sie! Diese genaue Konfiguration gilt nur, wenn Sie die magische Kombination von:

    1. Ein Servlet 3.0-kompatibler Anwendungsserver wie Tomcat 7

    2. Ihre web.xml hat den richtigen Namespace für die Servlet 3.0-Spezifikation

    3. Sie haben diese drei JARS und keine anderen JSTL- oder Servlet-JARS auf Ihrem Klassenpfad.

  6. Stellen Sie sicher, dass Sie keine Kopien dieser JARs in Ihrem WEB-INF/lib-Verzeichnis ablegen, da sie in diesem Fall an den Server gesendet werden und dadurch LinkageErrors verursachen.

  7. In Ihrer JSP muss diese PRECISE-Zeile genau so formatiert sein, wie ich sie habe. Andernfalls jammert Eclipse, dass die c: blah-Tags nicht erkannt werden:

    <%@taglib uri="http://Java.Sun.com/jsp/jstl/core" prefix="c" %>
    
  8. Was für ein PITA! Dies ist VIEL schwerer zu implementieren als jede andere Version von JSTL. Dies ist das einzige Beispiel dafür, dass etwas in späteren Iterationen viel komplizierter als einfacher wird.

54
Tom Hunter

Ihr uri ist für JSTL 1.2 korrekt. Sie müssen zwei Dinge tun:

Ändere dein web.xml, um die neueste Web-App-Version zu verwenden.

Es sollte ungefähr so ​​aussehen oder eine spätere Version;

<?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">

Zweitens setzen Sie die richtige Version von JSTL-Gläsern in Ihren Code. Für 1.2 können Sie sie herunterladen hier .

Dies sollte Ihnen zwei Gläser geben:

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

Verwenden Sie diese anstelle von standard.jar und jstl.jar die für die vorherige Version waren.

Lassen Sie uns wissen, wie das bei Ihnen funktioniert.

14
VikC

Für die Ausführung unter Apache Tomcat 7 ist es wahrscheinlich angebracht, diese in Ihren POM aufzunehmen. Diese Gläser verweisen nicht wie die Glassfish-Gläser auf javax.servlet-Gläser, sodass keine Ausschlüsse erforderlich sind.

<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
K.Nicholas

Für Tomcat gibt es eine einfachere Abhängigkeitslösung für 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>

Siehe hier für weitere Details (persönlicher Blog).

REM: Wenn Sie weitere Details wünschen, müssen Sie JSTL-Abhängigkeiten einbeziehen, um sie auf Tomcat verfügbar zu machen. Version 1.2 ist jedoch nicht unbedingt erforderlich, da Version 1.1.2 (von Apache wie Tomcat bereitgestellt) ebenfalls die Aufgabe übernimmt. Die einzige Voraussetzung ist Servlet 2.4 und JSP 2.2, und das OP erwähnt Servlet 3.0 und JSP 2.0, was gut genug ist.

0

Hier gibt es zwei Antworten, die im Hinblick auf die Lösung dieses Problems bei der Verwendung von Maven zur Behebung dieses Problems größtenteils richtig sind. Beide sind jedoch nicht zu 100% vollständig.

Verwenden von Ausschlüssen per @ Tom Jägers Antwort

Diese Antwort funktioniert. Es werden jedoch weiterhin Protokollmeldungen von Tomcat zu doppelten TLD-Definitionen angezeigt. Dies liegt daran, dass sowohl die Artefakte jstl als auch jstl-impl die TLD-Definitionen enthalten. Um diese Nachrichten zu entfernen, ist meines Erachtens das folgende Maven-Setup besser:

<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>

Dies schließt nur die JSTL-API-Klassen mit den erforderlichen Ausschlüssen ein, um die im Rest dieser Antwort erläuterten Probleme zu vermeiden.

Verwenden neuerer POM-Versionen gemäß @ Georges Antwort

Es hat eine Weile gedauert, bis ich es realisiert habe, aber es gibt neuere Versionen der JSTL-Poms. Das ist sehr verwirrend, da diese neueren Pakete ähnliche, aber leicht unterschiedliche Namenskonventionen verwenden. Diese neueren Versionen kennzeichnen die Abhängigkeiten javax.servlet, javax.jsp usw. als angegebenen Bereich, sodass sie nicht ausgeschlossen werden müssen. Die 1.2.1-Version hängt von einer 1.2.1-Version der JSTL-API ab. Und so funktioniert dies würde genauso wie die obige Antwort:

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

Dies unterscheidet sich geringfügig von Georges Antwort, da ich den Gültigkeitsbereich auf Laufzeit umgestellt habe. George hat den Umfang wie angegeben angegeben. Mit einem bereitgestellten Bereich müssten die JAR-Dateien manuell in das Tomcat-Lib-Verzeichnis kopiert werden, oder eine andere Abhängigkeit müsste die erforderliche Implementierung enthalten.

Allerdings Ich konnte die 1.2.1-Version des Werkzeugs in maven central, jboss repo oder einer anderen nicht finden andere Repos. Am Ende drehte ich mich im Kreis und benutzte schließlich nur ein lokales dateibasiertes Repo, um das Glas zu speichern. Die Abhängigkeit und das Jar werden hier beschrieben:

0
kaliatech

Keines davon funktionierte für mich. Ich habe das Projekt einfach erstellt, ohne Maven zu verwenden und die JAR-Dateien direkt hinzuzufügen.

0
CommonCoreTawan