clientDisconnected info.reason nullPointer

Hi, I’m having a NullPointer when I’m trying to display the reason for the disconnection. I can print it out, but when I try to display it in the gui or try to “see” what’s inside with an If-statement I get a nullPointer :s



Server:

[java]source.close(“byebye”);[/java]



Client first attempt:

[java]Gui.setStatusText(info.reason));[/java]



Client second attempt:

[java]

if(info.reason.equals(“byebye”)){

Gui.setStatusText(“closing connection”);

}else{

[/java]



NullPointer:

[java]SEVERE: Uncaught exception thrown in Thread[com.jme3.network.kernel.tcp.SocketConnector@164cbde,5,main]

java.lang.NullPointerException

at network.ClientListener.clientDisconnected(ClientListener.java:103)

at com.jme3.network.base.DefaultClient.fireDisconnected(DefaultClient.java:294)

at com.jme3.network.base.DefaultClient.close(DefaultClient.java:249)

at com.jme3.network.base.DefaultClient.dispatch(DefaultClient.java:316)

at com.jme3.network.base.DefaultClient$Redispatch.messageReceived(DefaultClient.java:331)

at com.jme3.network.base.ConnectorAdapter.dispatch(ConnectorAdapter.java:101)

at com.jme3.network.base.ConnectorAdapter.run(ConnectorAdapter.java:130)[/java]

I cannot see enough of your code to know what’s going on and I’m unclear on the sequence of events.



Can you show me what your ClientListener looks like around line 103 or is that what’s posted above?



Is it that clientDisconnected is being called twice by SM or something?



In my app I can kick clients and it only delivers the event once. So there are other factors at play.



And note: for a variety of reasons there may not be a reason in the disconnect info. Only in the case where the server provided one. But the connection could drop for any of a hundred causes and then you’ll get an event with no reason.

The line 103 is what I posted yes. And it is the only thing in the clientDisconnected method.

It’s actually based on the monkeyzone code. But normen just uses the info and not info.reason. But then it just gives me null.



I only call source.close() once in my program



[java]

if (msg.version != 1) {

source.close(“byebye”);

return;

}[/java]



but what I find strange is when I do System.out.println(info.reason); It gives me the actual reason I sent :s

Can you show me the code that prints the reason and the code that throws the NPE in more context? specifically marking the exact line where the NPE happens. For example, can I see the whole clientDisconnected() method? Is that also where you are printing the reason?



There is nothing in SM that ever sets reason to null So if it’s not null in one place then it should be not null everywhere unless a) your code is changing it, or b) it’s not the same info object… or alternately, it’s not null at all and the NPE is from something else entirely.



And note: in general practice, info.reason can be null for many valid reasons (say the user unplugged their network cable). So the equals check you have will throw an NPE in those cases, too. It’s better to do something like “byebye”.equals( info.reason ) since that won’t NPE in those cases.



…but let’s figure out where your strangeness is coming from first. :slight_smile:

Hmm seems you are right about the two times :s I added a new screen and in debug window I see it gets called twice, but I don’t know where it is comming from

server:

[java]

if (message instanceof HandshakeMessage) {

HandshakeMessage msg = (HandshakeMessage) message;

Logger.getLogger(ServerListener.class.getName()).log(Level.INFO, “Got handshake message”);

//checken van of client versie up to date is

if (msg.client_version != Integer.parseInt(XMLHandler.getInfo(“client_version”))) {

source.close(“out of date”); //<-Sending reason for closing

Logger.getLogger(ServerListener.class.getName()).log(Level.INFO, “Client protocol mismatch, disconnecting”);

return;

}

msg.server_version = 1;

source.send(msg);

Logger.getLogger(ServerListener.class.getName()).log(Level.INFO, “Sent back handshake message”);

} [/java]

Client:

[java]

public void messageReceived(Object source, Message message) {

if (message instanceof HandshakeMessage) {

HandshakeMessage msg = (HandshakeMessage) message;

Logger.getLogger(ClientListener.class.getName()).log(Level.INFO, “Got handshake message back”);

if (msg.client_version != 1) {

Gui.setStatusText(“Version is out of date - update client!”);

Logger.getLogger(ClientListener.class.getName()).log(Level.INFO, “Client protocol mismatch, disconnecting”);

} else {

//TODO: wachtwoord variable maken

client.send(new ClientJoinMessage(XMLHandler.getInfo(“username”), “wachtwoord”));

}

}

}

public void clientConnected(Client c) {

Gui.setStatusText(“Connection successful… Checking version”);

gamePointer.enqueue(new Callable<Void>() {

public Void call() throws Exception {

HandshakeMessage msg = new HandshakeMessage(Integer.parseInt(XMLHandler.getInfo(“clientversion”)), Integer.parseInt(XMLHandler.getInfo(“serverversion”)));

client.send(msg);

Logger.getLogger(ClientListener.class.getName()).log(Level.INFO, “Sent handshake message”);

return null;

}

});

}

public void clientDisconnected(Client c, DisconnectInfo info) {

//String test = info.reason.intern();

Gui.changeScreen(“Error”);

System.out.println(info);

System.out.println(info.reason); //<- NPE line: 106

Gui.setStatusText(info.reason);

//Gui.setStatusText(“Connection failed:n Client is out of date - please update to a newer versionn” + test);

}

[/java]

[java]3-mei-2011 13:12:07 network.ClientListener$2 call

INFO: Sent handshake message

3-mei-2011 13:12:07 com.jme3.network.base.DefaultClient dispatch

SEVERE: Connection terminated, reason:out of date.

3-mei-2011 13:12:07 de.lessvoid.nifty.Nifty gotoScreen

INFO: gotoScreen [Error]

3-mei-2011 13:12:07 de.lessvoid.nifty.screen.Screen$EndScreenEndNotify perform

INFO: onEndScreen has ended

3-mei-2011 13:12:07 de.lessvoid.nifty.Nifty gotoScreenInternal

INFO: gotoScreenInternal [Error]

3-mei-2011 13:12:07 de.lessvoid.nifty.screen.Screen$StartScreenEndNotify perform

INFO: onStartScreen has ended

com.jme3.network.ClientStateListener$DisconnectInfo@10e7c9e

out of date

3-mei-2011 13:12:07 de.lessvoid.nifty.Nifty gotoScreen

INFO: gotoScreen [Error]

3-mei-2011 13:12:07 de.lessvoid.nifty.screen.Screen$EndScreenEndNotify perform

INFO: onEndScreen has ended

3-mei-2011 13:12:07 de.lessvoid.nifty.Nifty gotoScreenInternal

INFO: gotoScreenInternal [Error]

3-mei-2011 13:12:07 de.lessvoid.nifty.screen.Screen findNiftyControl

null

INFO: onStartScreen has ended

3-mei-2011 13:12:07 com.jme3.app.Application handleError

SEVERE: Uncaught exception thrown in Thread[com.jme3.network.kernel.tcp.SocketConnector@c5122f,5,main]

java.lang.NullPointerException

at network.ClientListener.clientDisconnected(ClientListener.java:106)

at com.jme3.network.base.DefaultClient.fireDisconnected(DefaultClient.java:294)

at com.jme3.network.base.DefaultClient.close(DefaultClient.java:249)

at com.jme3.network.base.DefaultClient.dispatch(DefaultClient.java:316)

at com.jme3.network.base.DefaultClient$Redispatch.messageReceived(DefaultClient.java:331)

at com.jme3.network.base.ConnectorAdapter.dispatch(ConnectorAdapter.java:101)

at com.jme3.network.base.ConnectorAdapter.run(ConnectorAdapter.java:130)

3-mei-2011 13:12:07 com.jme3.input.lwjgl.LwjglMouseInput destroy

INFO: Mouse destroyed.

3-mei-2011 13:12:07 com.jme3.input.lwjgl.LwjglKeyInput destroy

INFO: Keyboard destroyed.

3-mei-2011 13:12:07 com.jme3.system.lwjgl.LwjglAbstractDisplay deinitInThread

INFO: Display destroyed.[/java]

It looks like this is the problem “b) it’s not the same info object… or alternately, it’s not null at all and the NPE is from something else entirely.”

But I only send close once :s

could it be that the close command is being send internally with no info?

or when does cliendDisconnect gets called? I call it when the version isn’t up to date, but from what I see from the debugger it gets called again with no info… so just a guess here, could it be that it’s called when client realizes there isn’t a connection anymore?

Ok, the only case where an info object is null (it’s not the reason that’s null… it’s the info object given your NPE)… is when client.close() is called.



The “bug” in SM is that it doesn’t check to see if the client is already closed when calling close(). At any rate, it sends new clientDisconnected() events with a null info object.



On the one hand, SM can probably be fixed not to do this if the connection is already closed. On the other hand, you’re going to have to update your ClientListener to handle nulls anyway… since a normal close() would have also caused them.



P.S.: The version check you are using your handshake for is also built right into SpiderMonkey. Just create a server with a version and client with a version and SM will do this checks for you.

Could you tell me how I can check if the info object is null, I tried several things, but it just isn’t working.

I tried to make a new DisconnectInfo object but it appears to be that it isn’t null and it isn’t the best way either I guess




Ok I got it, thanks for your help pspeed!



[java] String empty;

try{

empty = info.toString();

}catch(Exception e){

Logger.getLogger(ClientListener.class.getName()).log(Level.SEVERE, “info message error”, e);

empty = “”;

}



if(!empty.equals("")){

Gui.changeScreen(“Error”);

Gui.setStatusText(“nConnection failed:nVersion out of daten” + info.reason);

}[/java]

dgeronimo said:
Could you tell me how I can check if the info object is null, I tried several things, but it just isn't working.
I tried to make a new DisconnectInfo object but it appears to be that it isn't null and it isn't the best way either I guess


[java]public void clientDisconnected(Client c, DisconnectInfo info) {
//String test = info.reason.intern();
Gui.changeScreen("Error");
if(info != null)
{
System.out.println(info);
System.out.println(info.reason); //<- NPE line: 106
Gui.setStatusText(info.reason);
}
//Gui.setStatusText("Connection failed:n Client is out of date - please update to a newer versionn" + test);
}[/java]