Forum: PC-Programmierung loadClass-Problem bei Java-servlet. Resourcen-Problem?


von Jürgen W. (lovos)


Angehängte Dateien:

Lesenswert?

Hallo,
bei meinem Servlet wird angehaengte Exception geworfen.

EDIT:
den Anhang kann nicht oeffnen, obwohl er eine Textdatei ist.
Die ersten Zeilen sind
1
30.11.2010 11:28:57 org.apache.catalina.loader.WebappClassLoader loadClass
2
INFO: Illegal access: this web application instance has been stopped already.  Could not load inet.htmlbas.  The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
3
java.lang.IllegalStateException
4
  at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1273)
5
  at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
6
  at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
7
  at inet.httpthr.readhtml(httpthr.java:178)
8
  at inet.httpthr.transfer_http(httpthr.java:306)
9
  at inet.httpthr.get_http(httpthr.java:237)
10
  at inet.fileUpload3.doPost(fileUpload3.java:133)


Angeblich koennen Klassen nicht geladen werden, die aber definitiv im 
richtigen Verzeichnis vorhanden sind. Auch die File-Permissions stimmen.

Auf meinem lokalen Tomcat passiert das nicht, nur auf dem 
mivitec-Webserver
(Der lokale Tomcat benutzt exakt die gleichen Dateien, auch web.xml)
Nach langem Suchen konnte ich die das Problem durch einen Hack beheben:
Bei Beginn der doPost-Funktion allokier ich schon einmal ein 
htmlbas-Objekt und andere Klassen.
Wenn das schon am Anfang geladen wurde, dann kann er das auch an der 
kritischen Stelle laden.

Ich habe das Tomcat-Mini von
http://webhosting.mivitec.de/tomcat-provider/Jspservlets.html
Bei diesem Paket ist TOMCAT - RAM (Arbeitsspeicher für Ihre 
Tomcat-Instanz) auf 64 MB beschraenkt.

Da dachte ich an Speicherplatzproblem.
An den kritischen Stellen gab ich Memory-Info aus:
1
Runtime runtime=Runtime.getRuntime();
2
long memtot = runtime.totalMemory();
3
long memfree= runtime.freeMemory();
4
out.println("memtot="+(memtot/1024)+
5
  "kiB ,memfree="+(memfree/1024)+"kiB<br/>\n");
6
7
memtot=64704kiB ,memfree=27627kiB
8
memtot=64704kiB ,memfree=27574kiB
9
memtot=64768kiB ,memfree=25407kiB

Daran sollte es nicht liegen. Meine paar Arrays sind nur maximal 0x4000 
lang.
Im Vergleich hat das gleiche Programm als Desktop-PC-Programm folgende 
ausgaben:
1
memtot=15552kiB, memfree=15276kiB
und da enstand nie eine classLoad Exception.

Weiss jemand, woher das obige Problem kommt? Der Workaround mit dem 
vorherigen Laden von spaeter benoetigten Klassen gefaellt mir nicht.

Gruss, Juergen

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

> this web application instance has been stopped already ...
> and has no functional impact
Du versuchst da irgenwas außer der Reihe zu machen das Ihm (Tomcat) 
nicht gefällt...

von Jürgen W. (lovos)


Lesenswert?

>Du versuchst da irgenwas außer der Reihe zu machen das Ihm (Tomcat)
>nicht gefällt...

Hmm... was kann das sein? Normalerweise wird ja wegen jeder Kleinigkeit 
eine Exception geworfen, so dass man gezwungen wird in Java sauber zu 
programmieren.
Mein lokaler Tomcat jammert ja auch nicht.
Also schliesst du Ressourcen-Probleme aus?

Nachtrag:
Der Code umfasst mehrere 1000 Zeilen, so dass ich ihn nicht reinstelle. 
Da ist nichts besonderes drin, halt was man zum Parsen von html-Seiten 
braucht, z.B. vieles hin und her- kopieren von String[]-Arrays.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Jürgen G. schrieb:
>>Du versuchst da irgenwas außer der Reihe zu machen das Ihm (Tomcat)
>>nicht gefällt...
> Hmm... was kann das sein? Normalerweise wird ja wegen jeder Kleinigkeit
> eine Exception geworfen,
Nö, nur well ein fehlerhafter Zustand erreicht wird. Hier ein 
sogenannter "Ungültiger Zustand", d.h. in einem (Web)Modul wird versucht 
eine Klasse zu laden mittels eines Classloaders der zu einer Applikation 
gehört welche als beendet gekennzeichnet wurde... läuft da eventuell ein 
Thread im hintergrund weiter?

> Also schliesst du Ressourcen-Probleme aus?
Resourcenproblem wäre eine ClassNotFoundException, hier verweigert der 
Classloader generell den Dienst (in einem ServletContainer ist ein 
Classloader normalerweise nur für "seinen" Context zuständig um 
Fehler/Angriffe zu verhindern)

> Nachtrag:
> Der Code umfasst mehrere 1000 Zeilen, so dass ich ihn nicht reinstelle.
Sollange Teile auskommentieren bis der Fehler nicht mehr auftritt und so 
das Problem einkreisen oder debugger bemühen.

> Da ist nichts besonderes drin, halt was man zum Parsen von html-Seiten
> braucht
Parsen? Oder ausgeben? Für das ausgeben gibt es StringBuilder (oder man 
schreibt direkt in den ResponseWriter) und fürs Parsen bringt Java schon 
einen eingebauten HTMLParser mit wenn auch etwas versteckt...
> vieles hin und her- kopieren von String[]-Arrays
Hört sich verdächtig nach falschem Konzept an...

von Jürgen W. (lovos)


Lesenswert?

>> vieles hin und her- kopieren von String[]-Arrays
>Hört sich verdächtig nach falschem Konzept an...

Darueber kann man unterschiedlicher Meinung sein.
Ich achte sehr auf einfache Strukturen, Uebersichtlichkeit.
Dieses Programm habe ich schon vor 6 Jahre angefangen als 
Desktop-Programm und dann staendig erweitert nach Erfordernissen. Jetzt 
wuerde ich schon einiges anders machen.

>> Da ist nichts besonderes drin, halt was man zum Parsen von html-Seiten
>> braucht
>Parsen? Oder ausgeben? Für das ausgeben gibt es StringBuilder (oder man
>schreibt direkt in den ResponseWriter) und fürs Parsen bringt Java schon

Html Parsen, Form-Felder ausfuellen, posten und kurze Status-Meldungen. 
(D.h. auf PrintWriter out = response.getWriter(); wird ganz wenig 
geschrieben.
Hoert sich einfach an, aber die Klassen sollen das fuer alle moeglichen 
Arten von Html-Seiten machen koennen.

>Sollange Teile auskommentieren bis der Fehler nicht mehr auftritt und so
>das Problem einkreisen oder debugger bemühen.
Genau das habe ich fuer meinen Workaroung gemacht.
Irgendwann hatte ich einen Schrumpf-Code, der funktioniert. Dann habe 
ich festgestellt, dass auch der Hauptcode laeuft, wenn vorher ein paar 
Klassen schon benutzt wurden (in dem Schrumpf-Code).
Durch logisches Denken waere ich nie darauf gekommen.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Wie gesagt, du musst da irgendwie was Nebenläufiges drinne haben, oder 
eine andere Konfiguration des Classpath zwischen "Server"<-->"Zuhause"

von Jürgen W. (lovos)


Lesenswert?

Tja, mir fehlen auch etwas Grundlagen. Java SE kenne ich zwar sehr gut, 
ein wenig Java ME, die Webprogrammierung mit PHP sehr gut, aber 
J2EE/JSP/Servlets ist total neu fuer mich.
Vielleicht kommt die Loesung, wenn ich tiefer einsteige; solange muss 
das Workaround taugen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.