Holger: ParseException: Invalid Directive beim Einbinden von JavaBean

Gute Abend,

ich habe eine jsp-datei unter meinem Verzeichnis für Webapplikationen abgelegt.
Dort wird mit
<%@ import="myjavabeans.*" %>
ein einfaches Javabean HelloWorld.class eingebunden, das unter WEB-INF/classes/myjavabeans/ liegt.

Danach soll die JSP Datei mit HelloWorld.sagHallo("Holger"); eine Ausgabe vom JavaBean erzeugen.

Wenn ich das versuche, erscheint folgender Fehler:
---------schnipp---------
org.apache.jasper.compiler.ParseException: /opt/hpapache2/tomcat/webapps/keychain/buypower/support_tools/userinterface.jsp(4,4) Invalid directive
 at org.apache.jasper.compiler.Parser$Directive.accept(Parser.java:186)
 at org.apache.jasper.compiler.Parser.parse(Parser.java:1077)
 at org.apache.jasper.compiler.Parser.parse(Parser.java:1042)
 at org.apache.jasper.compiler.Parser.parse(Parser.java:1038)
 at org.apache.jasper.compiler.Compiler.compile(Compiler.java:209)
 at org.apache.tomcat.facade.JasperLiaison.jsp2java(JspInterceptor.java:790)
 at org.apache.tomcat.facade.JasperLiaison.processJspFile(JspInterceptor.java:731)
 at org.apache.tomcat.facade.JspInterceptor.requestMap(JspInterceptor.java:506)
 at org.apache.tomcat.core.ContextManager.processRequest(ContextManager.java:968)
 at org.apache.tomcat.core.ContextManager.internalService(ContextManager.java:875)
 at org.apache.tomcat.core.ContextManager.service(ContextManager.java:833)
 at org.apache.tomcat.modules.server.Ajp13Interceptor.processConnection(Ajp13Interceptor.java:341)
 at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:494)
 at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:516)
 at java.lang.Thread.run(Thread.java:536)
---------schnapp---------
Was mache ich falsch? Wird im Ordner classes noch eine Datei namens web.xml benötigt?
Zuerst habe ich das JavaBean mit <jsp:useBean eingebunden, aber es tauchte ein ähnlicher Fehler auf. Es scheint, als ob meine Klassenstruktur nicht erkannt wird.

Vielen Dank im voraus,
Holger

  1. Hallo,

    ich habe eine jsp-datei unter meinem Verzeichnis für Webapplikationen abgelegt.
    Dort wird mit
    <%@ import="myjavabeans.*" %>

    Die Direktive heißt korrekt <%@page import="Package" %>

    ein einfaches Javabean HelloWorld.class eingebunden, das unter WEB-INF/classes/myjavabeans/ liegt.

    Nein, mit der genannten Direktive importierst du höchstens Klassen.
    Du bindest dort (noch) nichts ein.

    Sollte es das nicht gewesen sein, dann wäre es nicht verkehrt, wenn
    du mal die ersten 5 Zeilen der JSP-Datei hier posten würdest.

    Gruß
    Slyh

    --
    Es gibt 10 Arten von Menschen. Solche, die das Binärsystem verstehen, und solche, die es nicht verstehen.
    Selfcode: sh:( fo:) ch:? rl:( br:^ n4:& ie:{ mo:} va:} de:] zu:) fl:( ss:) ls:/ js:|
    1. Hallo Slyh

      Sollte es das nicht gewesen sein, dann wäre es nicht verkehrt, wenn
      du mal die ersten 5 Zeilen der JSP-Datei hier posten würdest.

      habe es geschafft, ein Bean zum Laufen zu bringen. In der JSP-Datei sieht es wie folgt aus:

      -----------anfang------------------
      <%@ page language="java" %>

      <%-- *********************** --%>
      <%-- javaBeans are used here --%>
      <%-- *********************** --%>
      <jsp:useBean id="testname" class="myjavabeans.HelloWorld"/>

      (... hier folgt HTML Code ...)
      <h1><%= testname.sagHallo(sParam) %> </h1>
      (... hier folgt HTML Code ...)
      -----------ende--------------------

      Wenn ich nun ein anderes Bean einbinden möchte, das beispielsweise ByeWorld.java heisst und genau das gleiche macht, erhalte ich eine Fehlermeldung. (BTW: Natürlich habe ich die "public class" Angabe im Bean entsprechend den neuen Namen angepasst)
      Folgender Fehler tritt bei exakt dem gleichen Bean auf:

      -----------anfang------------------
      org.apache.jasper.JasperException: Unable to compile Note: sun.tools.javac.Main has been deprecated.
      /opt/hpapache2/tomcat/work/DEFAULT/keychain/buypower/support_tools/userinterface_9.java:68: Class myjavabeans.ByeWorld not found.
                          myjavabeans.ByeWorld testname = null;
                                     ^
      /opt/hpapache2/tomcat/work/DEFAULT/keychain/buypower/support_tools/userinterface_9.java:71: Class myjavabeans.ByeWorld not found.
                              testname= (myjavabeans.ByeWorld)
                                                    ^
      /opt/hpapache2/tomcat/work/DEFAULT/keychain/buypower/support_tools/userinterface_9.java:76: Class myjavabeans.ByeWorld not found.
                                    testname = (myjavabeans.ByeWorld) java.beans.Beans.instantiate(this.getClass().getClassLoader(), "myjavabeans.ByeWorld");
                                                           ^
      3 errors, 1 warning
      -----------ende--------------------

      Anscheinend wird ByeWorld.class nicht gefunden, obwohl sie exakt genau dort liegt, wo HelloWorld.class (<- das funktionierende) auch liegt und genau den gleichen Code beinhaltet.
      JSP ist frustrierend. In Perl hätte ich meine Aufgabe in ein paar Stunden erledigt. Naja, vielleicht kann mich jemand von dem Gegenteil überzeugen...

      LG aus Dublin,
      Holger

      1. Hi,

        Anscheinend wird ByeWorld.class nicht gefunden, obwohl sie exakt genau dort liegt, wo HelloWorld.class (<- das funktionierende) auch liegt und genau den gleichen Code beinhaltet.

        Du hast BywWorld.java auch ohne Fehler kompiliert? Ist die Dateilänge vielleicht zufälligerweise gleich <0>?

        Bitte 'mal folgendes probieren:
        1. Alle Java-Klassen neu kompilieren. Um das sicherzustellen, vorher alle bereits existierenden class-Files löschen.

        2. Lösche das gesamte 'work'-Verzeichnis von Tomcat.

        3. Starte Tomcat und rufe die URL auf.

        Was passiert?

        JSP ist frustrierend. In Perl hätte ich meine Aufgabe in ein paar Stunden erledigt. Naja, vielleicht kann mich jemand von dem Gegenteil überzeugen...

        Ich gehe davon, aus, dass Du Perl beherrschst, hingegen gerade erst beginnst, Dich mit JSP-Technologie zu beschäftigen. Genau _das_ ist der Grund dafür, dass Du 'mehr als ein paar Stunden' brauchst.

        Viele Grüße,
        Martin Jung

        1. Vielen Dank für die Anregungen, Martin,
          habe es wie folgt versucht:
          1.) alle Files und Ordner unter work gelöscht
          2.) Tomcat neu gestartet. Apache muss ja nicht neu gestartet werden, oder?
          3.) Das JavaBean HelloWorld.java nach HelloWorld2.java kopiert. Und im File HelloWorld2.java nur "public class HelloWorld" zu "public class HelloWorld2" geändert.
          4.) JavaBean HelloWorld.java eingebunden, alles läuft
          5.) JavaBean HelloWorld2.java eingebunden, der vorher genannte Fehler tritt auf

          Ich gehe davon, aus, dass Du Perl beherrschst, hingegen gerade erst beginnst, Dich mit JSP-Technologie zu beschäftigen. Genau _das_ ist der Grund dafür, dass Du 'mehr als ein paar Stunden' brauchst.

          Stimmt. Aber dennoch sehe ich, dass im Vergleich zu den prozeduralen Sprachen wie ASP, PHP und Perl, JSP um einiges schwieriger zu erlernen ist. Und neben der Objektorientierung gibt es noch einen weiteren Grund: Es bestehen einfach sehr wenige Tutorials, für Java-Anfänger. Die meisten Tutorials erwarten, dass man schon Java perfekt beherrscht, wenn man mit JSP anfängt.

          1. Kleine Korrektur, sorry:

            Vielen Dank für die Anregungen, Martin,
            habe es wie folgt versucht:
            1.) alle Files und Ordner unter work gelöscht
            2.) Tomcat neu gestartet. Apache muss ja nicht neu gestartet werden, oder?
            3.) Das JavaBean HelloWorld.java nach HelloWorld2.java kopiert. Und im File HelloWorld2.java nur "public class HelloWorld" zu "public class HelloWorld2" geändert.

            3.1) HelloWorld2 und HelloWorld neu kompiliert.
            4.) JavaBean HelloWorld.class eingebunden, alles läuft
            5.) JavaBean HelloWorld2.class eingebunden, der vorher genannte

          2. Hi,

            2.) Tomcat neu gestartet. Apache muss ja nicht neu gestartet werden, oder?

            Keine Ahnung, ich habe Tomcat bisher immer nur Standalone verwendet. Einleuchtend wäre allerdings, dass Apache nicht neu gestartet werden müsste.

            5.) JavaBean HelloWorld2.java eingebunden, der vorher genannte Fehler tritt auf

            Ok (die Korrektur habe ich gelesen), ich fürchte, Du müsstest den Code beider Beans (natürlich in den fehlererzeugenden Versionen) und der JSP hier 'mal komplett posten.

            Stimmt. Aber dennoch sehe ich, dass im Vergleich zu den prozeduralen Sprachen wie ASP, PHP und Perl, JSP um einiges schwieriger zu erlernen ist. Und neben der Objektorientierung gibt es noch einen weiteren Grund: Es bestehen einfach sehr wenige Tutorials, für Java-Anfänger. Die meisten Tutorials erwarten, dass man schon Java perfekt beherrscht, wenn man mit JSP anfängt.

            Letzteres macht auch Sinn, denn JSP-Technologie ist nicht 'irgendetwas, was irgendwie' mit Java zu zusammenhängt. JSP ist Java mit einigen Syntax-Erweiterungen, die die Entwicklung von Web-basierten Anwendungen erleichtern soll. Hinter der Einführung der JSP-Technologie steckten u.a. auch vielfältig geäußerte Wünsche aus größeren Projekten, in welchen eine klare Rollenteilung praktiziert wird. Auf der einen Seite gibt es die Rolle der Entwickler/Programmierer. Diese kümmern sich z.B. um die Beans, Servlets und all die andere Java-Umsetzung (= Programmier-/Kontrollflusslogik). Eine weitere Rolle ist die der Web-Oberflächen-Zusammenbauer, die sich eben vorwiegend genau auf Letzteres konzentrieren sollen. Bei konsequenter Umsetzung des MVC-Prinzips (logische Separation von Daten, Kontrollflusslogik und Oberfläche) wird man als JSP-'Entwickler' (=Web-Oberflächen-Zusammenbauer) u.U. hauptsächlich mit XML-, aber sehr wenig mit Java-Syntax konfrontiert. Du aber musst/willst beide Rollen gleichzeitig ausüben - du musst Dich also mit Java beschäftigen. Nach meinem Dafürhalten lohnt sich das auch.

            Viele Grüße,
            Martin Jung

            1. Hallo Martin,

              natürlich lohnt sich Java. Und die MVC-Trennung ist ganz klar ein Punkt, der für diese Sprache spricht.

              Hier ist der Code meines 1. JavaBeans: HelloWorld.class
              ----------------------Anfang-----------------------------
              package myjavabeans;

              public class HelloWorld {
                public static String sagHallo(String sInput)
                {
               return("Herzlich Willkommen " + sInput);
                }
              }
              -----------------------Ende------------------------------

              Hier das ist der Code meines 2. JavaBeans: HelloWorld2.class
              ----------------------Anfang-----------------------------
              package myjavabeans;

              public class HelloWorld2 {
                public static String sagHallo(String sInput)
                {
               return("Herzlich Willkommen " + sInput);
                }
              }
              -----------------------Ende------------------------------

              Und hier der Code meines JSPs:

              ----------------------Anfang-----------------------------
              <%@ page language="java" %>

              <%-- *********************** --%>
              <%-- javaBeans are used here --%>
              <%-- *********************** --%>

              <jsp:useBean id="testname" class="myjavabeans.HelloWorld"/>

              <%-- ***************************************** --%>
              <%-- header and left navigation are sourced in --%>
              <%-- ***************************************** --%>

              <jsp:include page="inc_header.jsp" flush="true">
                <jsp:param name="titel" value="Edit Userinterface"/>
              </jsp:include>

              <jsp:include page="inc_leftnav.jsp" flush="true">
                <jsp:param name="titel" value="Edit Userinterface"/>
              </jsp:include>

              <%-- ************************* --%>
              <%-- start of the HTML content --%>
              <%-- ************************* --%>

              <br>
              <b>Current user interface of the Buypower customer web site:</b>
              <br>
              <table bgcolor=black cellpadding=0 cellspacing=1 width=600>
              <tr><td><table bgcolor=white cellpadding=0 cellspacing=20 width=600>
               <tr><td align=center>
                 <%@ include file="static/index.status.content.txt" %>
               </td></tr>
               </table>
                  </td></tr>
              </table>

              <%
              String sParam = request.getParameter("param");
              if (sParam != null)
              {
              %>

              <h1><%= testname.sagHallo(sParam) %> </h1>
              <%
              }
              else
              {
              %>
              <h3>Wie ist Ihr Name?</h3>
              <form action="userinterface.jsp" method="post">
              Name: <input type="text" name="param"><br>
              <input type="submit" value=" Abschicken ">
              </form>
              <%
              }
              %>

              <%-- ********************* --%>
              <%-- trailer is sourced in --%>
              <%-- ********************* --%>
              <%@ include file="inc_bottom.jsp" %>
              -----------------------Ende------------------------------

              Wie gesagt, dieser Code funktioniert, aber sobald ich "myjavabeans.HelloWorld" durch "myjavabeans.HelloWorld2" ersetze, kommt die beschriebene Meldung.

              Meine Applikation liegt unter TOMCAT_HOME/webapps/keychain/buypower/support_tools/userinterface.jsp

              Meine beiden JavaBeans liegen unter
              TOMCAT_HOME/webapps/keychain/buypower/support_tools/WEB-INF/classes/myjavabeans/HelloWorld.class

              1. Hallo,

                ich muss nun doch erneut melden.
                Habe eben festgestellt, dass auch HelloWorld.class nicht gefunden wird. Lag das daran, dass der work Ordner gelöscht wurde?
                Also, es funktionieren beide nicht.

                Bin dankbar für jeden Hinweis,
                Holger

                1. Hi Holger,

                  @MVC: das ist ein so genanntes Design-Pattern, dass unabhängig von der Implementierungssprache ist.

                  Habe eben festgestellt, dass auch HelloWorld.class nicht gefunden wird. Lag das daran, dass der work Ordner gelöscht wurde?

                  Nein, im Work-Folder liegen die aus den JSPs vom JSP-Compiler generierten Java-Dateien (die normale Servlets darstellen), die dann wiederum vom Java-Compiler in class-Files kompiliert werden.

                  Ich bin mir ziemlich sicher, das Problem ist der WEB-INF Pfad:
                  TOMCAT_HOME/webapps/keychain/buypower/support_tools/WEB-INF/classes/myjavabeans/HelloWorld.class

                  Aus dem Kopf sage ich, dass ich _nicht_ konform mit den Tomcat-Spezifikationen, nach das WEB-Inf-Verzeichnis _direkt_ unter der Root-Verzeichnis der Web-Appliaktion (=<keychain>) erwartet wird - deswegen findet Tomcat beim Kompilieren der JSP-Servlets auch keine der verwendeten Beans.

                  Also, verschiebe WEB-INF so, dass gilt <TOMCAT_HOME/webapps/keychain/WEB-INF/classes/myjavabeans/HelloWorld.class> und probiere es nochmal.

                  Viele Grüße,
                  Martin Jung

                  1. Hi Holger,

                    @MVC: das ist ein so genanntes Design-Pattern, dass unabhängig von der Implementierungssprache ist.

                    Stimmt auch wieder. Aber das MVC Konzept lässt sich nahezu ideal in JSP umsetzen.

                    Aus dem Kopf sage ich, dass ich _nicht_ konform mit den Tomcat-Spezifikationen, nach das WEB-Inf-Verzeichnis _direkt_ unter der Root-Verzeichnis der Web-Appliaktion (=<keychain>) erwartet wird - deswegen findet Tomcat beim Kompilieren der JSP-Servlets auch keine der verwendeten Beans.

                    Un was ist mit unseren unternehmensinternen Spezifikationen? Müssen die sich denen von Tomcat unterordnen?

                    Also, verschiebe WEB-INF so, dass gilt <TOMCAT_HOME/webapps/keychain/WEB-INF/classes/myjavabeans/HelloWorld.class> und probiere es nochmal.

                    Habe ich gemacht. Funktioniert nicht.
                    Wie in der Doc beschrieben, habe ich in der Datei TOMCAT_HOME/conf/jk/mod_jk.conf das hier eingetragen:
                    JkMount /keychain/buypower/support_tools/*.jsp ajp13

                    Darüber hinaus habe ich wie in der Doc geschildert eine Datei namens apps.xml unter TOMCAT_HOME/conf erstellt und darin folgendes eingetragen:
                    <?xml version="1.0" encoding="ISO-8859-1"?>
                    <webapps>
                        <!-- Special rules for the admin webapplication -->

                    <!-- Change "trusted" to true in order to run the admin -->
                        <Context path="/support_tools"
                                 docBase="/keychain/buypower/support_tools"
                                 reloadable="true"
                                 trusted="false" >
                                <SimpleRealm filename="conf/users/admin-users.xml" />
                        </Context>
                    </webapps>

                    Reicht das nicht aus, um Tomcat mitzuteilen, dass meine Applikation in diesen Ordnern liegt? Was muss man noch eintragen, um eine neue Web-Applikation zu erzeugen?

                    Wenn ich WEB-INF unter keychain lege, funktionieren die Skripts auch nicht. Ich sehe jetzt keinen Grund dafür, warum auf einmal beide JavaBeans nicht funktionieren.
                    JSPs im Order TOMCAT_HOME/webapps/test klappen, aber sobald ich sie in meinen kexchain ordner lege, geht gar nichts mehr.

                    Hm, ich spiele ernsthaft mit dem Gedanken, meinen Kater einzuschläfern...

                    Holger

                    1. Hi,

                      Un was ist mit unseren unternehmensinternen Spezifikationen? Müssen die sich denen von Tomcat unterordnen?

                      Was meinst Du mit 'unternehmensinternen Spezifikationen'?

                      Wie in der Doc beschrieben, habe ich in der Datei TOMCAT_HOME/conf/jk/mod_jk.conf das hier eingetragen:
                      JkMount /keychain/buypower/support_tools/*.jsp ajp13

                      Dazu kann ich mangels eigener Erfahrung auf die Schnelle Nichts sagen.

                      Darüber hinaus habe ich wie in der Doc geschildert eine Datei namens apps.xml unter TOMCAT_HOME/conf erstellt und darin folgendes eingetragen:
                      <?xml version="1.0" encoding="ISO-8859-1"?>
                      <webapps>
                          <!-- Special rules for the admin webapplication -->

                      <!-- Change "trusted" to true in order to run the admin -->
                          <Context path="/support_tools"
                                   docBase="/keychain/buypower/support_tools"
                                   reloadable="true"
                                   trusted="false" >
                                  <SimpleRealm filename="conf/users/admin-users.xml" />
                          </Context>
                      </webapps>

                      Auch hier habe ich keine praktische Erfahrung - hier geht es aber auf den ersten Blick nur um User-spezifische Zugriffsrestriktionen auf die Web-Appliaktion.

                      Reicht das nicht aus, um Tomcat mitzuteilen, dass meine Applikation in diesen Ordnern liegt? Was muss man noch eintragen, um eine neue Web-Applikation zu erzeugen?

                      Vor der direkten Antwort eine Frage: Funktioniert denn Deine Anwendung mit Tomcat im standalone-Modus? Wenn ja, ist die Umsetzung meiner folgenden Vorschläge nicht notwendig, und es sieht in der Tat so aus, als wäre das Problem in Deiner 'Zusatz'-Konfiguration und/oder der Apache-Anbindung zu suchen. Da kann ich aber leider nicht helfen.

                      Nun zur Frage - Umgekehrt wird ein Schuh daraus:
                      Im einfachsten Fall muss Du überhaupt kein Konfigurations-File anfassen bzw. editieren.
                      Per Default interpretiert Tomcat jeden TopLevel-Ordner _unter_ dem Ordner <webapps> als eine individuelle Web-Applikation, d.h. alles unter dem dort liegenden WEB-INF/classes bzw. WEB-INF/lib gehört dann _automatisch_ zum classpath dieser WebAnwendung.
                      Das kannst Du schnell verfizieren. Generiere <TOMCAT_HOME/webapps/test> und lege darin eine <hallo.html> mit Inhalt Deiner Wahl. Starte Tomcat standalone und rufe http://localhost/test/hallo.html (vorausgesetzt, der <Http1xConnector> aus der <conf/server.xml> hat Port-Wert 80) auf. Wird die Datei angezeigt, ist alles bis hierher ok (d.h., Tomcat 'kennt' die Webanwendung <test>, ohne dass diese in irgendeiner Konfigurations-Datei explizit registriert wurde). Dann erweitere das Beispiel, indem Du Deine JSP-Datei in diese Test-Anwendung kopierst (vielleicht zuerst ohne Zugriff auf die Beans), dann die Beans nach <TOMCAT_HOME/webapps/test/WEB-INF/classes> usw.. So, wenn immer noch alles funktioniert, nachdem der Aufbau der <test>-Applikation bis auf den Namen _identisch_ mit der bisher fehlerhaften <kexchain>-Applikation ist, bist Du wieder ein Stück weiter, dann liegt es nämlich an der 'Zusatz'-Konfiguration und/oder der Apache-Anbindung (s.o.).

                      Wenn ich WEB-INF unter keychain lege, funktionieren die Skripts auch nicht. Ich sehe jetzt keinen Grund dafür, warum auf einmal beide JavaBeans nicht funktionieren.

                      Das ist zu ungenau. Dein Problem scheint so subtil, dass es bei der Beschreibung wirklich auf Exaktheit ankommt. Welche _Scripts_ funktionieren jetzt nicht - ich dachte, es geht um JSPs und JavaBeans?

                      JSPs im Order TOMCAT_HOME/webapps/test klappen, aber sobald ich sie in meinen kexchain ordner lege, geht gar nichts mehr.

                      Welche JSPs? Irgendwelche oder _die_ eine (siehe Beispiel oben)?

                      Hm, ich spiele ernsthaft mit dem Gedanken, meinen Kater einzuschläfern...

                      Der kann nun wirklich nichts dafür...

                      Viele Grüße,
                      Martin Jung