PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit Vererbung in Java


Gast
2005-09-11, 15:23:43
Ich mache gerade ein Tutorial für JSP, in dem es darum geht, einen Stundenplan zu erstellen.

Dazu benutze ich folgende Klasse:

public class ScheduleServlet extends HttpServlet implements Servlet {

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}


Die Methode doPost habe ich eingeklappt, sie scheint nämlich nichts zur Sache zu tun.

Ich benutze Eclipse. Eclipse unterstreicht mein "ScheduleServlet" gelb, und wenn ich mit der Maus darüber fahre, erscheint folgender Text:

The serializable class ScheduleServlet does not declare a static final
serialVersionUID field of type long


Wenn ich folgende Zeile hinzufüge:

static final long serialVersionUID;


Ist ScheduleServlet nicht mehr gelb unterstrichen, dafür aber "serialVersionUID" rot, und die Meldung von Eclipse dazu lautet:

The blank final field serialVersionUID may not have been initialized


Was ja auch irgendwo logisch ist ...


Kann mir jemand sagen, was ich hier falsch mache, bzw. woran das liegen könnte?

SgtTynis
2005-09-11, 16:11:21
Ich bin nicht der Java Guru, aber das du das statische Feld angelegt hast erscheint mir erst mal richtig, jetzt musst du es nur noch mit einem Wert versehen z.B. static final long serialVersionUID = 1;.

Gast
2005-09-11, 16:20:00
Ja, dann ist der Fehler weg.

Jetzt hab ich das Programm getestet, und das hier kommt:

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.lang.IllegalStateException: Cannot forward after response has been committed
org.eclipse.wtp.sample.classschedule.ScheduleServlet.doPost(ScheduleServlet.java :45)
javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

note The full stack trace of the root cause is available in the Apache Tomcat/5.0.28 logs.
Apache Tomcat/5.0.28

HellHorse
2005-09-11, 18:11:02
Ich bin nicht der Java Guru, aber das du das statische Feld angelegt hast erscheint mir erst mal richtig, jetzt musst du es nur noch mit einem Wert versehen z.B. static final long serialVersionUID = 1;.
Das ist ganz, ganz fest pfui.
Dafür gibt es serialver.

Senior Sanchez
2005-09-11, 19:23:54
Ich mache gerade ein Tutorial für JSP, in dem es darum geht, einen Stundenplan zu erstellen.

Dazu benutze ich folgende Klasse:

public class ScheduleServlet extends HttpServlet implements Servlet {

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}


Die Methode doPost habe ich eingeklappt, sie scheint nämlich nichts zur Sache zu tun.

Ich benutze Eclipse. Eclipse unterstreicht mein "ScheduleServlet" gelb, und wenn ich mit der Maus darüber fahre, erscheint folgender Text:


Wenn ich folgende Zeile hinzufüge:

static final long serialVersionUID;


Ist ScheduleServlet nicht mehr gelb unterstrichen, dafür aber "serialVersionUID" rot, und die Meldung von Eclipse dazu lautet:


Was ja auch irgendwo logisch ist ...


Kann mir jemand sagen, was ich hier falsch mache, bzw. woran das liegen könnte?


doPost tut schon etwas ;) es verarbeitet nämlich nen Post-Request der bei deiner JSP/Servlet ankommt und verarbeitet werden will. Schaue dir dazu mal das hier an: http://www.galileocomputing.de/openbook/javainsel4/javainsel_17_000.htm#Xxx999380

die Sache mit der serialVersionUID unterkringelt Eclipse zwar, brauchste dir im Grunde aber keine Sorgen zu machen. Afaik dient die serialVersionUID dazu um eine Version einer Klasse exakt identifizieren zu können. Jedes Mal wenn ne neue Version der Klasse kompiliert wird, ändert sich dann die serialVersionUID und über diverse checks kann dann festgestellt werden, ob die anderen klassen auch mit der richtigen Version arbeiten.

Ist natürlich die Frage, warum man ne serialVersionUID einfügen soll und soweit ich weiß, solls nen bissl Geschwindigkeit bringen oder kann auch dazu benutzt wird um eine Interaktion zwischen Klassen trotz einer eigentlich ungültigen UID manuell zu erzwingen.

HellHorse
2005-09-11, 20:33:31
die Sache mit der serialVersionUID unterkringelt Eclipse zwar, brauchste dir im Grunde aber keine Sorgen zu machen. Afaik dient die serialVersionUID dazu um eine Version einer Klasse exakt identifizieren zu können. Jedes Mal wenn ne neue Version der Klasse kompiliert wird, ändert sich dann die serialVersionUID und über diverse checks kann dann festgestellt werden, ob die anderen klassen auch mit der richtigen Version arbeiten.
Afaik nein. Afaik dient es zur eindeutigen Identifizierung kompatibler Versionen einer Klasse.
Beispiel:
Instanz von A wird serialisiert.
A wird krass refactored.
Serialisierte Instanz von A soll deserialisiert werden -> kompatibel zu A?

Ist natürlich die Frage, warum man ne serialVersionUID einfügen soll und soweit ich weiß, solls nen bissl Geschwindigkeit bringen oder kann auch dazu benutzt wird um eine Interaktion zwischen Klassen trotz einer eigentlich ungültigen UID manuell zu erzwingen.
http://java.sun.com/j2se/1.5.0/docs/api/java/io/Serializable.html
http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html#wp4100

Aber serialisation ist sowieso ein Geschichte für sich. Und ich bin mir nicht sicher, ob serialVersionUID mit Java > 1.1 wirlich noch nötig ist.

Auf jeden Fall ist überall 1 hinschreiben eine doofe Idee, besser ganz weglassen.

@Mods
die hier beschriebenen Probleme haben nichts mit Vererbung zu tun, wäre schön wenn man den Threadtitel ändern kann.

Senior Sanchez
2005-09-11, 21:01:01
Afaik nein. Afaik dient es zur eindeutigen Identifizierung kompatibler Versionen einer Klasse.
Beispiel:
Instanz von A wird serialisiert.
A wird krass refactored.
Serialisierte Instanz von A soll deserialisiert werden -> kompatibel zu A?

http://java.sun.com/j2se/1.5.0/docs/api/java/io/Serializable.html
http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html#wp4100

Aber serialisation ist sowieso ein Geschichte für sich. Und ich bin mir nicht sicher, ob serialVersionUID mit Java > 1.1 wirlich noch nötig ist.

Auf jeden Fall ist überall 1 hinschreiben eine doofe Idee, besser ganz weglassen.

@Mods
die hier beschriebenen Probleme haben nichts mit Vererbung zu tun, wäre schön wenn man den Threadtitel ändern kann.


Hast recht. Das war etwas was ich öfter bei meinen RMI-Sachen zu lesen bekam, ich weiß aber net mehr weshalb. *g* Ich glaube da gings um die ganzen Stubs usw., da kam das manchmal, wenn ich nicht komplett neugebaut habe. Hat also auch etwas mit Kompatibilität zwischen Versionen zu tun. Überall 1 hinzuschreiben ist in der Tat blöd.

Gast
2005-09-12, 01:16:16
Hm, dann hängt oben genannter Fehler wohl nicht damit zusammen.

Könnt ihr mir denn helfen, die Fehlermeldung besser zu verstehen? Mir sagt das nicht gerade viel ...

Gast
2005-09-12, 09:54:11
Hier ist mal die Methode doPost, damit ihr den Fehler auch nachvollziehen könnt :D

Wenn ich das richtig verstehe, so darf ich vor dem Forwarden nichts senden, aber wo wird denn hier etwas gesendet?


protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPost(request, response);

String title = request.getParameter("title");
int starttime = Integer.parseInt(request.getParameter("starttime"));
int endtime = Integer.parseInt(request.getParameter("endtime"));
String[] days = request.getParameterValues("day");

SchoolSchedule schedule = (SchoolSchedule)request.getSession(true).getAttribute("schoolschedule");
if (schedule == null) {
schedule = new SchoolSchedule();
}

if (days != null) {
for (int i = 0; i < days.length; i++) {
String dayString = days[i];
int day;
if (dayString.equalsIgnoreCase("SUN")) day = 0;
else if (dayString.equalsIgnoreCase("MON")) day = 1;
else if (dayString.equalsIgnoreCase("TUE")) day = 2;
else if (dayString.equalsIgnoreCase("WED")) day = 3;
else if (dayString.equalsIgnoreCase("THU")) day = 4;
else if (dayString.equalsIgnoreCase("FRI")) day = 5;
else day = 6;

SchoolClass clazz = new SchoolClass(title, starttime, endtime, day);
schedule.addClass(clazz);
}
}
request.getSession().setAttribute("schoolschedule", schedule);
getServletContext().getRequestDispatcher("/Schedule.jsp").forward(request, response);
}

Senior Sanchez
2005-09-12, 10:37:38
Hier ist mal die Methode doPost, damit ihr den Fehler auch nachvollziehen könnt :D

Wenn ich das richtig verstehe, so darf ich vor dem Forwarden nichts senden, aber wo wird denn hier etwas gesendet?


protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
super.doPost(request, response);

String title = request.getParameter("title");
int starttime = Integer.parseInt(request.getParameter("starttime"));
int endtime = Integer.parseInt(request.getParameter("endtime"));
String[] days = request.getParameterValues("day");

SchoolSchedule schedule = (SchoolSchedule)request.getSession(true).getAttribute("schoolschedule");
if (schedule == null) {
schedule = new SchoolSchedule();
}

if (days != null) {
for (int i = 0; i < days.length; i++) {
String dayString = days[i];
int day;
if (dayString.equalsIgnoreCase("SUN")) day = 0;
else if (dayString.equalsIgnoreCase("MON")) day = 1;
else if (dayString.equalsIgnoreCase("TUE")) day = 2;
else if (dayString.equalsIgnoreCase("WED")) day = 3;
else if (dayString.equalsIgnoreCase("THU")) day = 4;
else if (dayString.equalsIgnoreCase("FRI")) day = 5;
else day = 6;

SchoolClass clazz = new SchoolClass(title, starttime, endtime, day);
schedule.addClass(clazz);
}
}
request.getSession().setAttribute("schoolschedule", schedule);
getServletContext().getRequestDispatcher("/Schedule.jsp").forward(request, response);
}



Ui, Servlet-Programmierung ist lange her bei mir *g* Aber was soll das super.doPost am Methodenanfang?

Monger
2005-09-12, 11:12:31
Hier ist mal die Methode doPost, damit ihr den Fehler auch nachvollziehen könnt :D

Wenn ich das richtig verstehe, so darf ich vor dem Forwarden nichts senden, aber wo wird denn hier etwas gesendet?


Wenn ich jetzt nicht völlig schief gewickelt bin, schickst du deine Antwort bereits raus, indem du super.doPost(...) aufrufst. Genau diese Methode willst du ja durch deine eigene Implementierung ersetzen.

Du selbst antwortest imo, indem du

getServletContext().getRequestDispatcher("/Schedule.jsp").forward(request, response);

aufrufst. Der Request Dispatcher sorgt afaik dafür, dass Requests mit einer Response beantwortet werden. (Wahrscheinlich, indem der Client an eine Adresse mit bestimmten Parametern weitergeleitet wird)

Wenn das so funktioniert was ich mal gelernt habe, hat die Response ein Flag, was anzeigt ob sie fertig ist, so dass sie zurückgeschickt werden kann. Durch dein "super.doPost(...)" ist dieses Flag bereits gesetzt, d.h. die Antwort wurde schon rausgeschossen, und du hast keine Chance mehr, selber an der Antwort noch was zu ändern.

Gast
2005-09-12, 11:17:52
Ja, genau das war es, super! (im wahrsten Sinne des Wortes ;))

Aber das hat Eclipse beim ich-klicke-mir-eine-Methode-zusammen-und-frag-nicht-nach verbrochen.

Wahrscheinlich hat der TODO Eintrag da zu bedeuten, dass ich das ändern soll.

Danke jedenfalls!

Senior Sanchez
2005-09-12, 11:35:52
Ja, genau das war es, super! (im wahrsten Sinne des Wortes ;))

Aber das hat Eclipse beim ich-klicke-mir-eine-Methode-zusammen-und-frag-nicht-nach verbrochen.

Wahrscheinlich hat der TODO Eintrag da zu bedeuten, dass ich das ändern soll.

Danke jedenfalls!

Lag ich also schon richtig mit meiner Vermutung. Kleiner Tipp: Man sollte die Kommentare und Meldungen von Eclipse doch ab und zu mal lesen ;)

Senior Sanchez
2005-09-14, 12:22:56
Lag ich also schon richtig mit meiner Vermutung. Kleiner Tipp: Man sollte die Kommentare und Meldungen von Eclipse doch ab und zu mal lesen ;)

EDIT: Hier noch was interessantes zur SUID: http://www.galileocomputing.de/openbook/javainsel4/javainsel_12_013.htm#Rxx365java12013040004031F014214