# NullPointerException...finde den Fehler nicht



## luzze (1. Sep 2009)

Hallo zusammen,

ich bin noch ein ziemlicher noob was Java betrifft und erst seit einigen Wochen ernsthaft dabei etwas mit Java zu programmieren...komme von Delpi und PHP, die ja nicht so strikt sind 

Mein Problem:
Ich habe mir einen kleinen Socket ChatServer zusammen gebastelt, der auch wunderbar funktioniert, läuft mit Threads, Clientpool,mehreren Räumen usw. Das problem ist nur, wenn sich ein Client ausklinkt, bekomme ich eine NullPointerException...allerdings nur in der Konsole, beim Client wird nichts ausgegeben, der Server läuft auch normal weiter, ohne Probleme. Theoretisch könnte ich das Problem also auch einfach ignorieren...ist aber wohl nicht die feine Art  Hier mal mein Code:


```
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Vector;


public class ChatServer {

  // Anfang Attribute
    public static final int DEFAULT_PORT = 9800;
    public static final int MAX_CLIENTS = 100;
    public static final String SERVER_VERSION = "1.0";
  // Ende Attribute


  // Anfang Methoden
    public static void main(String[] args) {
  int port = DEFAULT_PORT;
  ServerSocket serverSocket = null;
  Socket socket = null;
  try {
      if(args.length > 0)
          port = Integer.parseInt(args[0]);
          System.out.println("\n[CHATSERVER v"+SERVER_VERSION+"]");
          System.out.println("Copyright Grandlose.de, all rights reserved\n");
          System.out.println("\nMaximum Clients: "+MAX_CLIENTS);
          System.out.println("running Chatserver on Port "+port+" successfull...");
          System.out.println("listen for new Clients...");
          
  } catch(NumberFormatException nfe) {
      System.err.println("Usage: java ChatServer [port]");
      System.err.println("Where options include:");
      System.err.println("\tport the port on which to listen.");
      System.exit(0);
  }
  try {
      serverSocket = new ServerSocket(port);
      while(true) {
          socket = serverSocket.accept();
          ChatServerHandler handler = new ChatServerHandler(socket);
          handler.start();
      }
  } catch(IOException ioe) {
      ioe.printStackTrace();
  } finally {
      try {
          serverSocket.close();
      } catch(IOException ioe) {
    ioe.printStackTrace();
      }
  }
    }
  // Ende Methoden
}


class ChatServerHandler extends Thread {

  // Anfang Attribute1
  static final String SERVER_VERSION = "1.0";
  static final int MAX_CLIENTS = 10000;
  static Vector<ChatServerHandler> handlers = new Vector<ChatServerHandler>( MAX_CLIENTS );
  private boolean registered = false;
  private String username;
  private String ucolor;
  private String room;
  private Socket socket;
  private BufferedReader in;
  private PrintWriter out;
  private String login;
  // Ende Attribute1


    public ChatServerHandler(Socket socket) throws IOException {
        this.socket = socket;
  in = new BufferedReader(
      new InputStreamReader(socket.getInputStream()));
  out = new PrintWriter(
      new OutputStreamWriter(socket.getOutputStream()));
    }

  // Anfang Methoden1
    public void run() {
    String line;
    String message;

  synchronized(handlers) {
      handlers.addElement(this);
 // add() not found in Vector class
  }
  try {
  if (!registered){
      login = in.readLine();
      String[] splittArray = login.split(">>");
      username=splittArray[0];
      room=splittArray[1];
      ucolor=splittArray[2];
      out.println("<b>Willkommen beim Chatserver</b>");
      out.flush();
      registered=true;
      for(int i = 0; i < handlers.size(); i++) {
      synchronized(handlers) {
                ChatServerHandler handler =
              (ChatServerHandler)handlers.elementAt(i);
              if (handler.room.equals(room)){
              handler.out.println("<i>***** "+username+" betritt den Raum *****</i>");
              handler.out.flush();
         }
      }
    }
      }
      while(!(line = in.readLine()).equalsIgnoreCase("/quit")) { //<--Dies ist die misteriöse Zeile 116
      String[] splittArray2 = line.split(">>");
      message=splittArray2[0];
      room=splittArray2[1];
      ucolor=splittArray2[2];
    for(int i = 0; i < handlers.size(); i++) {
      synchronized(handlers) {
                ChatServerHandler handler =
              (ChatServerHandler)handlers.elementAt(i);
              if (handler.room.equals(room)){
              handler.out.println("<font color=\"#"+ucolor+"\"><b>"+username+":</b> "+message+"</font>");
              handler.out.flush();
         }
      }
    }
      }
  } catch(IOException ioe) {
      ioe.printStackTrace();
  } finally {
      try {
    in.close();
    out.close();
    socket.close();
      } catch(IOException ioe) {
      } finally {
    synchronized(handlers) {
        handlers.removeElement(this);
    }
      }
  }
    }
  // Ende Methoden1
}
```

Der genaue Fehler:


```
Exception in thread "Thread-Nummer" java.lang.NullPointerException at ChatServerHandler.run<ChatServer.java:116>
```

Also,was ein NullPointerException ist weiß ich, aber ich werde da nicht schlau draus, wie das zustande kommt...ich dachte ich hätte alles abgefangen...Die Zeile 116, in der der Fehler beginnt...dieWhile-Schleife, bringt mich da auch nicht weiter.

Wäre nett, wenn mir hier mal jemand helfen könnte...Ich versuche da jetzt schon seit Tagen schlau draus zu werden...aber ich tendiere eher zur anderen Richtung

Gruss
luzze


----------



## Landei (1. Sep 2009)

Offenbar sendet der Client das "/quit" gar nicht, sondern ist schon "weg". in.readLine() liefert dann null, was zur NPE führt. Aber du solltest sowieso beides (null und "/quit") abfangen. Versuche mal 


```
while((line = in.readLine()) != null) {
         //ab hier ist sicher, dass line nicht null ist
         if (line.equalsIgnoreCase("/quit") {
            break; //verläßt auch die Schleife
         }
```


----------



## Spacerat (1. Sep 2009)

Ein ungeschriebenes Gesetz besagt:
	
	
	
	





```
definiert.equals(undefiniert);
```
Für deine Zeile 116 könnte das[JAVA=116]while(!"/quit".equalsIgnoreCase(line = in.readLine())) {
 // ...
}[/code]bedeuten. Nu' gibts auch keine NPE mehr. Allerdings muss in "in" nun irgendwann "/quit" auftauchen, sonst endets möglicherweise in einer IOException. Landeis Vorschlag hat also schon seine Vorzüge, weil bei mir "line" immer noch null werden kann.


----------



## luzze (1. Sep 2009)

Super,das war es :applaus: Besten Dank !! 

Das Problem ist, das ich einen Flash-Client verwende und Flash hat leider kein wirkliches onClose-Ereignis, so das ich wenn der Benutzer z.B.einfach den Browser schliesst kein "/Quit" mehr senden kann... Aber so funktioniert es.

Gruss


----------



## luzze (1. Sep 2009)

Mal noch eine allgemeine Frage ...wenn wir schon beim Thema sind 

Wieviele Threads kann ich hier bzw.Java oder von mir aus auch das OS gleichzeitig
verarbeiten und ab wann sollte man lieber zu machen ? Habt Ihr da schon Erfahrungen gemacht ? Gibt es vielleicht eine Empfehlung ?

Gruss


----------



## Landei (1. Sep 2009)

Kommt natürlich auf die Anwendung und vor allem auf die Anzahl der Prozessorkerne an. Jedenfalls nicht zu viele, sonst wächst der Verwaltungsaufwand unverhältnismäßig. Ein Thread-Pool mit Maximalzahl ist immer eine gute Idee, inzwischen gibt es mit Executer, Future usw. auch Möglichkeiten, sich die Verwaltung einfach zu machen.


----------



## luzze (1. Sep 2009)

Landei hat gesagt.:


> ... sonst wächst der Verwaltungsaufwand unverhältnismäßig.



Hmm, was soll ich mir jetzt unter Verwaltung vorstellen ? z.b. wird bei meinem obigen Script doch jeder Thread automatisch erstellt und ggf. wieder gelöscht ...was muss man da "verwalten" ?:bahnhof: Sorry wenn ich so blöd frage, aber das ist mir neu und irritiert mich gerade ein wenig ???:L

Gruss


----------



## Spacerat (1. Sep 2009)

Irritiert und Erledigt? Hmmm....
Aber was solls... Es ist ja nicht dein Verwaltungsaufwand, sonder jener der JVM. Also frei aus Monty Pythons "Sinn des Lebens": "Gaaaaar nichts müssen sie dabei tun gutes KInd... Sie sind nicht Qualifiziiiääärrt"


----------



## luzze (1. Sep 2009)

Ach...denn ist ja gut  Na ja, soll der Server doch was tun für sein Geld  
Wären 5000 Threads bei 2 Kernen und 2GB RAM zu hoch gegriffen ? Nehmen wir jetzt mal das Beispiel des obigen Chatservers. Und wenn die max. Anzahl erreicht ist...könnte man irgendwie die Clienten auf einen 2 Server umleiten und trotzdem am geschehen teilhaben lassen ? Wohl eher nicht oder ? Man müsste dem 2 Server ja sonst irgendwie den Thread-Pool übergeben und wäre somit wieder bei der Ausgangssituation...


----------



## Spacerat (1. Sep 2009)

Hoffe du bist des Englisch mächtig: Java Virtual Machine (JVM) - maximum Thread count depends on max. heap size ?
Angesichts dessen bin ich relativ verwirrt... :autsch:


----------



## luzze (1. Sep 2009)

Das find ich jetzt aber ziemlich blöd ueh: Wenn JVM eh bei 2GB zu macht und es schon ab 500 Threads kritisch wird...dann sollte ich mir vielleicht was anderes überlegen...
Ich hab da was von nio läuten hören, das man ohne threads auskommt..aber da werde ich wohl als anfänger meine probleme haben...hab mich bei dem ja schon ordentlich gequält.
Oder gibt es irgendwo n vernünftiges tut ? Hab gerade mal bei xSocket geschaut...aber irgendwie leuchtet mir das noch nicht so ganz ein 

Gruss

Edit:
Anderseits würde das bedeuten, das zumindest 500 gleichzeitig angemeldet sein müssen...was ja schon ne Menge ist...hmm, aber dann hat der Server wohl auch keine Luft mehr sich noch um http aufrufe zu kümmern :noe:


----------

