Exception in thread "thread-4" java.lang.NullPointerException - java

I'd really appreciate some help with my program
Exception in thread "Thread-4" java.lang.NullPointerException
at ServerConnect.replyChoice(BaseStaInstance.java:63)
at ServerConnect.run(BaseStaInstance.java:45)
at java.lang.Thread.run(Thread.java:619)
my ServerConnect function looks like :-
class ServerConnect extends Thread {
Socket skt;
String sProcessId;
ServerConnect scnt = null;
ObjectOutputStream myOutput;
ObjectInputStream myInput;
ServerConnect(){}
ServerConnect(Socket connection, String sProcessNo) {
this.skt = connection;
this.sProcessId = sProcessNo;
}
public void run() {
try {
myInput = new ObjectInputStream(skt.getInputStream());
ServerConnect scnt = new ServerConnect();
while(true) {
try{
int ownTimeStamp = Global.iTimeStamp;
Object buf = myInput.readObject();
//if we got input, print it out and write a message back to the remote client...
if(buf != null){
LINE 45--> **scnt.replyChoice(buf);**
}
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
}
} catch(IOException e) {
e.printStackTrace();
}
}
void replyChoice(Object buf){
try{
LINE 63 --> **myOutput = new ObjectOutputStream(skt.getOutputStream());**
System.out.println("Server read:[ "+buf+" ]");
myOutput.writeObject("got it");
myOutput.flush();
}catch(IOException e){
e.printStackTrace();
}
}
}
Its basically a socket programming and multithreaded application. On executing it on different terminals inorder to have the client and server establish connections, I execute my code. But it throws up the error above on both terminals. Its just got something to do with my declaring the myOutput variable at the wrong place. Could someone help me out.
From the error message, I've highlighted line 63 and line 45 in the piece of code attached.

Drop the default constructor
Make your instance fields (stk and sProrcessId) final
See how your compiler complains and fix those issues
These instructons help you trading runtime errors like your NPE to compile time errors, which is the best thing you can do. Note: This trick is meant to be used in general.

Your object is being initialised with the first constructor, which takes no parameters. As a result, skt is never initialised and is therefore null. When you call skt.getOutputStream(), it throws a null pointer exception because it cannot dereference skt.

ServerConnect(){}
ServerConnect(Socket connection, String sProcessNo) {
this.skt = connection;
this.sProcessId = sProcessNo;
}
what constructor do you use ? cause skt might be uninitialised
//Edit : oh i see now you use the wrong constructor
ServerConnect scnt = new ServerConnect();
to
ServerConnect scnt = new ServerConnect(skt,sProcessId);

Related

Detecting when a client has disconnected from my server [duplicate]

This question already has answers here:
Java socket API: How to tell if a connection has been closed?
(9 answers)
Closed 5 years ago.
I'm trying to find a way to see when a client that is connected to my server has disconnected. The general structure of my code is like this, I have omitted irrelevant sections of my code:
public class Server {
public static void main(String[] args) {
...
try {
ServerSocket socket = new ServerSocket(port);
while (true) {
// wait for connection
Socket connection = socket.accept();
// create client socket and start
Clients c = new Server().new Clients(connection);
c.start();
System.out.printf("A client with IP %s has connected.\n",c.ip.substring(1) );
}
} catch (IOException exception) {
System.out.println("Error: " + exception);
}
}
class Clients extends Thread {
...
public Clients(Socket socket) {
clientSocket = socket;
ip=clientSocket.getRemoteSocketAddress().toString();
try {
client_in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
client_out = new PrintWriter(clientSocket.getOutputStream(), true);
} catch (IOException e) {
//error
}
}
public void run() {
...
try {
while (true) {
while ((message = client_in.readLine()) != null) {
...
}
}
} catch (IOException exception) {
System.out.printf("Client with IP %s has disconnected.\n" , ip.substring(1));
}
}
}
}
Basically what I'm trying at the moment is detecting the disconnection through the catch statement in run(), but the issue with this is it doesn't display the message until I terminate my server.
I have also tried to put my print statement after the while(true) loop but my IDE tells me that code is unreachable.
Is there a way to get my "Client with IP %s has disconnected." to display as soon as the client connection is disconnected? What and where should I be checking?
what I'm trying to do is detecting the disconnection through the catch statement.
Bzzt. readLine() doesn't throw an exception at end of stream. It returns null. Any exception you catch here is an error, and should be reported as such.
while (true) {
while ((message = client_in.readLine()) != null) {
...
}
The problem is here. You are detecting when the peer disconnects: readLine() returns null and terminates the inner loop. However you have pointlessly enclosed the correct inner read loop in an outer while (true) loop, which by definition can never exit.
Remove the outer loop.

Java Chat Server (Socket) - how to write unit test?

I have written a Java Chat Server program.
This is a simple standalone program for Server.
I have to run this then run Client to get Chat working.
What are some possible Unit Test scenarios for the server program? Can anyone show me some example of unit test based on this code?
I have never written a unit test code before and I can't really think of what needs to be tested here.. I think testing Connection can be one but what else? (and how to?)
public class SimpleChatServer {
static final Logger logger = LogManager.getLogger(SimpleChatServer.class);
ArrayList<PrintWriter> clientOutputStreams;
private BufferedReader reader;
private Socket sock;
private ServerSocket serverSock;
public class ClientHandler implements Runnable{
public ClientHandler(Socket clientSocket){ // Socket Connection
try {
sock = clientSocket;
InputStreamReader isReader = new InputStreamReader(sock.getInputStream());
reader = new BufferedReader(isReader);
} catch(Exception ex) {
logger.trace(ex);
}
}
public void run() {
String message;
try {
while ((message = reader.readLine()) != null) {
System.out.println("read " + message);
tellEveryone(message);
}
} catch(Exception ex) {
logger.trace(ex);
}
} //close run
} //close ClientHandler
public static void main (String[] args) throws Exception
{
new SimpleChatServer().listen();
}
#SuppressWarnings("resource")
public void listen()
{
clientOutputStreams = new ArrayList<PrintWriter>();
try {
ServerSocket serverSock = new ServerSocket(8000); //port number 8000 was used
while(true) {
Socket clientSocket = serverSock.accept();
PrintWriter writer = new PrintWriter(clientSocket.getOutputStream());
clientOutputStreams.add(writer);
Thread t = new Thread(new ClientHandler(clientSocket));
t.start();
}
} catch (Exception ex) {
logger.trace("Server Error", ex);
} finally {
try
{
serverSock.close();
}
catch(Exception e){}
}
} // close go
public void tellEveryone(String message)
{
Iterator<PrintWriter> it = clientOutputStreams.iterator();
while(it.hasNext()) {
try {
PrintWriter writer = (PrintWriter) it.next();
writer.println(message);
writer.flush();
} catch (Exception ex) {
logger.trace(ex);
}
} // end while
} // close tellEveryone
}
I was going to crib an answer from Pragmatic Unit Testing, but suggest you just find a copy. At the very least you should consider whether results are right, whether your boundary conditions are correct, and if you can force error conditions.
Testing results often means making sure combinations of input get the expected results. Boundaries are reflected in the related "0, 1, many" rule, where you do silly stuff to see if your code has implicit boundaries that can be reached with bad, null or unexpected values.
For example, what happens if you pass huge Strings to your methods that take them? What about strings with weird Unicode chars in them? No line breaks?
Forcing error conditions means making sure things degrade gracefully and/or throw under the expected situation.
Think about your code as a brittle little appliance and then pretend a poo-flinging monkey, a 14-yr old hacker and your non-hacker grandmother (I know some exist) are all taking turns on it.

what is blocking the readLine() in this case? I tried sending \n or even byte arrays, is it a concurrency issue in my case?

I tried everything stack overflow has to offer on this common readLine problem. (sending \n, flushing out, changing to byte array style, becoming hermit, wrists )
I suspect in this case its a concurrency thing as Ispent well over 15 hours yesterday confirming that the only thing that isnt working is readline()!
I used loads of other versions like datareader with a byte array and making sure a \n got sent I even sent /ns just in case!
still my issue is the same, and I have ran out of ideas myself to solve the issue and have decided that somewhere, my problem is outside my understanding, just where? its got to be threading right?
I managed to get to read the socket to string that seemed to work so it IS blocking because reading the connection isnt working at all, the readline function is not the only way Ive had it as I said so in my snippets its not as developed as it has been but still the basic issue remains.
Please help, i dont know what the issue is
// So the main class initialises the socket objects and starts them in a thread, these work I get all sorts of flags letting me know that they are
void start_sockets() {
//if this is initiialised as a server and not a client
if (is_server) {
while (is_server) {
try {
System.out.println("listening for connection");
Sockject sj = new Sockject(server.accept());
sock_arr.add(sj);
System.out.println("server made connection ");
// once the connection is made the objects is started in a
// separate thread
new Thread(sock_arr.get(sock_arr.size() - 1)).start();
} catch (IOException e) {
}
}
} else { //else im running a client version of this class
// if the client socket isnt running in a thread, make it run
if (!running) {
new Thread(sj_client).start();
if (sj_client.sock.isConnected()) {
System.out.println("client thread connected to "
+ sj_client.sock.getLocalSocketAddress());
running = true;
}
}
}
}
//the inner class creates a socket object and puts it on an array or an object depending if the parent class is initialised to be a server or a client
class Sockject implements Runnable {
PrintWriter out;
BufferedReader in;
// a socket for processing
Socket sock;
// the constructor in this case initialises the input and output streams
Sockject(Socket s) {
sock = s;
try {
out = new PrintWriter(sock.getOutputStream());
in = new BufferedReader(new InputStreamReader(
this.sock.getInputStream()));
} catch (IOException e) {
close sockets
}
}
//tried variasions of this and similar, used data objects and been sennding /ns all over the shop
void recieve_data() throws IOException {
if (sock.isConnected()) {
if ((recieve = in.readLine()) != null) {
System.out.println("recieve says " + recieve);
}
}
}
// sends data to connection if it is cleared to send data
void send_data(String data) {
// send data called
if (clear_to_send == true) {
out.print(data);
out.flush();
clear_to_send = false;
}
}
#Override
public void run() {
while (threadloop ) {
try {
//code defo gets this far and with just send it keeps running forever so its defo recieve data thats the issue
send_data(send);
recieve_data();// <---I HATE YOU
} catch (IOException e) {
}
}
}
}
}
Now all of the above is ran in an instance of this class, in a thread of this class here these temporary functions are ran and are neversuccesfull
void servrecievex(){
System.out.println("NEVER GETS THIS FA THOUGH DOES IT");
for(int a = 0; a < net_flow.sock_arr.size(); a++){
if(net_flow.sock_arr.get(a).sock.isConnected()){
System.out.println("server recieve function");
net_flow.sj_client.clear_to_send = true;
net_flow.sock_arr.get(a).send_data("www /n \n");
System.out.println("RECIVEIFY!!!");
}
}
}
void clientsendx() {
net_flow.sj_client.clear_to_send = true;
net_flow.sj_client.send_data(Integer.toString(player1.posx) + "\n");
System.out.println("client sent stuff");
}

Concurrent Threads Reading a Socket

I have a simple Server-Client socket connection. I encapsulate all my data in objects which are sent backward and forward between the sockets, sent through ObjectStreams.
I have created a "HeartBeat" monitor, which runs in a separate thread, where both the server and the client, every 500ms, send a HeartBeat (empty object) backward and forward to check for connectivity, which works great. However, because of this, when I want to send other data between the server and client, it is mixed up with these HeartBeat objects.
For example my Server is expecting a Login object, but instead gets an object of instance HeartBeat.
My code is a simple client/server setup, so I don't think it'd be necessary to post their code, however, the HeartBeat code is as follows:
private static final int HEARTBEAT_INTERVAL = 500;
private void addHeartBeatMonitor(final Socket socket) {
this.heartBeatTimer = new Timer();
this.heartBeatTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
try {
ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());
os.writeObject(new HeartBeat());
ObjectInputStream is = new ObjectInputStream(socket.getInputStream());
if (!(is.readObject() instanceof HeartBeat)) { throw new IOException(); }
} catch (IOException e) {
LOG.info("Received disconnect from " + getClientSocket().getInetAddress());
heartBeatTimer.cancel();
if (clientSocket != null) {
try {
clientSocket.close();
} catch (IOException e1) {}
}
} catch (ClassNotFoundException e) {}
}
}, 0, HEARTBEAT_INTERVAL);
}
My options seem to be to as follows:
Ditch the HeartBeat functionality, although there seems to be no other reliable way to check the connection status.
Find some other kind of Socket implementation which will magically fix all of this for me.
Have a synchronized method which oversees all reads and writes to the socket, which discards HeartBeats and sends other objects where they're meant to be.
Some kind of synchronization magic.
Thanks in advance for any help!
EDIT:
Code which reads the Login object (server side):
User result = null;
try {
ObjectInputStream is = new ObjectInputStream(this.getInputStream());
Login request = (Login) is.readObject(); ### ERROR ###
result = this.mongoService.login(request);
ObjectOutputStream os = new ObjectOutputStream(this.getOutputStream());
os.writeObject(result);
} catch (IOException e) {
} catch (ClassNotFoundException e) {}
return result;
Exception as follows:
Exception in thread "Thread-0" java.lang.ClassCastException: model.HeartBeat cannot be cast to model.Login
at socket.SocketServerWorker.login(SocketServerWorker.java:78)
at socket.SocketServerWorker.<init>(SocketServerWorker.java:47)
at socket.SocketServer$2.run(SocketServer.java:50)
at java.lang.Thread.run(Thread.java:744)
Consider doing something like this. I just threw this together, so it's obviously untested, but I'm sure you'll get the idea:
public class HeartBeatMonitor
{
final Map<Class,Consumer> handlers = new HashMap<> ();
final Socket sock;
final ObjectInputStream is;
final ObjectOutputStream os;
public HeartBeatMonitor (final Socket sock)
{
try
{
this.sock = sock;
this.is = new ObjectInputStream (sock.getInputStream ());
this.os = new ObjectOutputStream (sock.getOutputStream ());
}
catch (final IOException e)
{
throw new RuntimeException (e);
}
}
public <T> void setHandler (final Class<T> type, final Consumer<? super T> handler)
{
this.handlers.put (type, handler);
}
// This would be called in a loop
void accept () throws ClassNotFoundException, IOException
{
final Object o = this.is.readObject ();
final Consumer handler = this.handlers.get (o.getClass ());
if (handler != null)
handler.accept (o);
// Else default handler?
}
}

SocketException Handling

I can`t understand something simple. I have a class that handles the socket input. I have a catch-clause:
public class EntryPoint implements Runnable {
private Socket socket = null;
private BufferedReader br = null; // receives data from the destination
...
public void run() {
String command = null; // buffer for holding one request from command line
StringReader commandReader = null; // stream for reading command
try {
while (!socket.isClosed() && (command = br.readLine()) != null) {
try {
command = command.trim();
commandReader = new StringReader(command);
Request req = JAXB.unmarshal(commandReader, Request.class);
commandReader.close();
dispatcher.sendRequest(req);
} catch(DataBindingException ex) {
response.sendResponse(SystemMessageFactory.INVALID);
response.sendResponse(SystemMessageFactory.SOCKET_SHUTDOWN);
}
}
} catch (SocketException e) {
System.out.println("Socket Exception");
} catch (IOException e) {
Logger.getLogger("server").log(Level.SEVERE,
"Error reading the command input of the client!", e);
}
}
}
When the peer abruptly shuts down the socket, the connection reset is sent. The stack trace is:
16.07.2013 1:39:51 EntryPoint run
SEVERE: Error reading the command input of the client!
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:168)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at blood.steel.server.EntryPoint.run(EntryPoint.java:36)
at java.lang.Thread.run(Thread.java:662)
How is it possible? I am catching it twice! SocketException is caught in its own catch-clause and in IOException catch clause. But nothing happens! It does not catch the socket exception. How can I handle it and what is the cause of such behaviour?
Either the SocketExceptioon is not the one in java.net. Check your imports.
Or you are not running the code you think you are.

Categories