NullPointerException in Thread's run method - java

I would really appreciate help with my program. It is some sort of chat server with multiple clients.
Here's the server code:
package com.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static int PORT;
private ServerSocket server;
private Socket socket;
public Server(int port) throws IOException {
PORT = port;
server = new ServerSocket(PORT);
System.out.println("server started");
try {
while (true) {
socket = server.accept();
try {
new ServeClient(socket);
} catch (IOException e) {
socket.close();
}
}
} finally {
server.close();
}
}
public static void main(String[] args) throws IOException {
int port = Integer.parseInt(args[0]);
Server server = new Server(port);
}
}
I start the server and then create a Client. The server receives connection socket from socket
and creates a ServeClient Thread.
Here's ServeClient code:
package com.server;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Vector;
import com.gui.WindowManager;
public class ServeClient extends Thread {
private final Socket socket;
private BufferedReader in;
private PrintWriter out;
private String msg;
public static final String ENDSTRING = "END";
public static Vector clients = new Vector();
public ServeClient(final Socket socket) throws IOException {
this.socket = socket;
System.out.println("socket " + socket);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream())), true);
start();
}
public void run() {
try {
clients.add(this);
while (true) {
msg = in.readLine();
if (msg == ENDSTRING)
break;
broadcast(msg);
}
System.out.println("closing...");
} catch (IOException e) {
System.err.println("IO EXCEPTION");
} finally {
try {
socket.close();
} catch (IOException e) {
System.err.println("SOCKET NOT CLOSED");
}
}
}
#SuppressWarnings("deprecation")
public void broadcast(String msg) {
synchronized (clients) {
Enumeration<ServeClient> e = clients.elements();
while (e.hasMoreElements()) {
ServeClient serveClient = e.nextElement();
try {
synchronized (serveClient.out) {
serveClient.out.println(msg);
}
} catch (Exception eee) {
serveClient.stop();
}
}
}
}
}
What i get is a NullPointerException when ServeClient invokes run() method
server started
socket Socket[addr=/127.0.0.1,port=51438,localport=8888]
Exception in thread "Thread-0" java.lang.NullPointerException
at com.server.ServeClient.run(ServeClient.java:33)
line 33 is the line with first "try" statement in ServeClient run() method

com.server.ServeClient.run(ServeClient.java:33)
I don't believe that it's happening at the try.
Open up an IDE, turn on debugging, and step through until you can see what's happening. That's the fastest way to figure out what you've missed.
There's an object that you're assuming is fine that is not. Find it.
Here's an example of how to do this properly:
http://www.kodejava.org/examples/216.html

Your problem is with the order in which static instance variables are initialised. Try doing something like:
...
private static Vector clients = null;
...
if (clients==null) {
clients = new Vector(); // consider putting this in a synchronized block
}
before you add the client to the vector.

Sorry for necroing such an old issue but it seemed like this problem wasn't resolved, so I'll give a bit of input from my end.
I've had a similar problem and the compiler also kept telling me that the problem was at the start() method. However, when I commented out the thread part and just ran the code on the same thread as the UI, the compiler directed me to the real source of the problem: the code inside the thread.
After making sure the code didn't give an error, I enclosed the code with the original thread code, and it stopped giving me the NullPointerException error.
Hope this helps someone along the way.

Remove the duplicate class declaration in JPanel.
I was trying to run a timer thread that updated a clock in the main application window.
I had created the JFrame with Eclipse/WindowBuilder and had followed a tutorial on how to make a timer. I had copied the declaration of the textfield into the class declaration to make it available for the entire class, but forgot to remove the Class Id in front of the widget definition. So it still initialized the local instance and not the global one. Thus when I accessed the global one it was still null.

Related

How to perform unit test on a server socket?

I am a beginner in Java. I have built a client-server group chat application watching tutorials. I read a lot about unit tests and can implement in simple maths problems but i don't know how does it work out for complex codes. So I want to see a demo of that which will make it easy to understand testing for rest parts. One part of the code is the 'server' class and it is:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//import java.awt.event.*;
public class Server {
private final ServerSocket s;
public Server(ServerSocket serverSocket)
{
this.s = serverSocket;
//this.display = display;
}
public void startServer() {
try {
// Listen for connections (clients to connect) on port 1234.
while (!s.isClosed()) {
// Will be closed in the Client Handler.
Socket socket = s.accept();
System.out.println("A new client has connected!");
ClientHandler clientHandler = new ClientHandler(socket);
Thread thread = new Thread(clientHandler);
// The start method begins the execution of a thread.
// When you call start() the run method is called.
// The operating system schedules the threads.
thread.start();
}
} catch (IOException e) {
closeServerSocket();
}
}
// Close the server socket gracefully.
public void closeServerSocket() {
try {
if (s != null) {
s.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// Run the program.
public static void main(String[] args) throws IOException {
ServerSocket s = new ServerSocket(1234);
Server server = new Server(s);
server.startServer();
}
}
and the test I want to perform are:
import static org.junit.Assert.*;
public class ServerTeste {
#org.junit.Test
public void startServer() {
}
#org.junit.Test
public void closeServerSocket() {
f
}
}
#org.junit.Test
public void main() {
}
}
NB: Apologies for any mistake because I am complete beginner.
Start the server in a separate thread, and connect to it like you would normally do

GUI frozen while waiting on an answer from the client

I'm currently having some issues running this small battleship program I am working on. I have two GUI, one for the server and one for the client. When I click the "Start Server" jButton, the program will freeze until it receives something from the client side.
Image of the GUI if it helps:
I have no issues unfreezing it by starting the client program, my issue is, how can I make it so that it just doesn't freeze while waiting? thanks a lot.
package battleship;
import javax.swing.JOptionPane;
import java.io.IOException;
import java.util.Scanner;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
/**
*
* #author ftonye
*/
public class BackGroundCom implements Runnable {
private int port;
private ServerSocket ss;
private Socket cs;
private Scanner reader;
private PrintStream writer;
public int missileIncomming;
public int missileOutgoing;
public Boolean dataToSend;
InetAddress sa = null;
public BackGroundCom(int port) {
this.port = port;
dataToSend = true;
missileOutgoing = 100;
startServer();
}
private void startServer() {
try {
sa = InetAddress.getLocalHost();
System.out.println(sa);
} catch (UnknownHostException ex) {
Logger.getLogger(BackGroundCom.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Server started");
try {
ss = new ServerSocket(this.port);
cs = ss.accept();
JOptionPane.showMessageDialog(null, "Server accept connection from" + cs.getInetAddress().getHostAddress());
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, ex.getMessage());
}
System.out.println("Server accept connection");
}
Part of my BattleSea.java, which is where I click the button before it freezes:
btnStartServer = new JButton("Start Server");
btnStartServer.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
com = new BackGroundCom(Integer.parseInt(txtPortNumber.getText().toString()));
t = new Thread(com);
t.start();
}
});
I am trying to understand how to get it to never freeze. Thanks
I expect that it is the call cs = ss.accept(); that is blocking. This is going to block until the client connects to the server. You run this in response to pushing the button, because in your button action code, you construct a BackGroundCom, and that object's constructor calls startServer, which executes this accept() line directly.
It seems like you are trying to set up the BackGroundCom object so that what it does occurs in a background thread, but what I describe above all happens before you create and run the thread. Maybe what you want to do is move the startServer call into the run() method of the BackGroundCom object. I don't see a run() method in BackGroundCom, although it implements Runnable. I assume it's further down in the code. Without it, this code wouldn't even compile.
Steve is right. ServerSocket.accept(); method will block until a connection is made. You have to put it inside another Thread so it won't block the EDT(Event Dispatching Thread). EDT is where your GUI runs.
public BackGroundCom(int port) {
this.port = port;
dataToSend = true;
missileOutgoing = 100;
new Thread(() -> (startServer()).start(); // run in new thread
}

java sockets address already in use exception

I'm facing a strange problem doing java sockets project. Here's my code:
Server:
package second.sockets;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class Server implements Runnable {
public static String HOST = "localhost";
public static int PORT = 1234;
private static final int MAX_USERS = 2;
private static final Server serverInstance = new Server();
private ServerSocket serverSocket;
private List<User> users = new ArrayList<>();
private Server() {
try {
if( this.serverSocket == null ) {
this.serverSocket = new ServerSocket(Server.PORT);
}
} catch(IOException e) {
e.printStackTrace();
System.err.println("could not initialize ServerSocket on port="+Server.PORT +
"["+ e.getMessage() +"]");
}
}
public static Server getInstance() {
return Server.serverInstance;
}
#Override
public void run() {
System.out.println("waiting for incoming connections...");
try {
while( !Thread.interrupted() ) {
this.waitForFreeSlots();
Socket newSocket=null;
try {
newSocket = this.serverSocket.accept();
System.out.println("new connection " + newSocket);
} catch(IOException e) {
System.err.println("could not connect");
}
}
} catch(InterruptedException e) {
System.err.println("server interrupted");
}
}
private synchronized void waitForFreeSlots() throws InterruptedException {
while( this.users.size() >= Server.MAX_USERS ) {
this.wait();
}
}
public static int getPORT() {
return PORT;
}
public static void main(String[] args) {
Server server = Server.getInstance();
Thread serverThread = new Thread(server);
serverThread.start();
}
}
Client:
package second.sockets;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) {
Socket socket=null;
try {
socket = new Socket(Server.HOST, Server.PORT);
} catch(UnknownHostException uhe) {
System.err.println("could not connect to "+Server.HOST+" on port "+Server.PORT+", no such host");
} catch(IOException ioe) {
System.err.println("could not connect to "+Server.HOST + " on port "+Server.PORT);
}
System.out.println(socket);
}
}
I run the server and it works, but when I run a Client I get could not initialize ServerSocket on port=1234[Address already in use: JVM_Bind] and it is from Server code from line 25. It's odd as Server is a singleton so there's no place for more than one instance of the class. What is more I don't even touch it in Client main function. I don't get it, any ideas where the problem is? Thanks.
EDIT:
Here's the stack trace. It comes from Server's constructor although it is private and it shows after running the Client.
java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:382)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at java.net.ServerSocket.<init>(ServerSocket.java:128)
at second.sockets.Server.<init>(Server.java:22)
at second.sockets.Server.<clinit>(Server.java:15)
at second.sockets.Client.main(Client.java:12)
could not initialize ServerSocket on port=21234[Address already in use: JVM_Bind]
Socket[addr=localhost/127.0.0.1,port=21234,localport=53054]
I don't get this transition:
at second.sockets.Client.main(Client.java:12)->at second.sockets.Server.<clinit>(Server.java:15)
The stuff you see in the exception comes from the fact that you are using Server.HOST and Server.PORT in your client code. This calls the class initializer for the Server class. In this initializer all the static stuff in the Server class is created. And I see you have a static Server instance there...so you have in fact several Server instances created.
So avoid using Server.HOST and Server.PORT in the client code and use the real valus directly and it will work.
Normally when you want to share stuff between 2 code entities, move them to a third entity to decouple the server and client. Then let server and client use that new entity.
Okay, I figured out what was wrong. In Client in this line socket = new Socket(Server.HOST, Server.PORT); I was using 2 variables from class Server. When I deleted it and pasted raw values or cahnge the variables to be final, it started to work. This is some wild magic.

client/server only reading one message?

my client/server works perfectly for one message, then no matter what's next it says it's blank.
I believe the problem resolves in here or my commands class:
package MyServer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
public class Main {
public static String line;
public static void main(String[] args){
while(true){
try {
//Creates a socket to receive commands from!
Socket socket = new Socket("localhost", 7586);
//Uses that socket to create a Reader to read the commands!
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//Waits for Lines to be sent and then executes them!
while(true){
line = in.readLine();
if(line != null){
Commands.ReceiveCommand();
}else {
break;
}
}
} catch (UnknownHostException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
or in my commands:
package MyServer;
import javax.swing.JOptionPane;
public class Commands {
static String command = (Main.line).toString(); //<--This was the problem, just had to move it into the method below.
public static void ReceiveCommand(){
if(command.equals("test")){
JOptionPane.showMessageDialog(null,"works","command: " + command,JOptionPane.WARNING_MESSAGE);
//System.out.println("WORKEDS MOFO");
command = "";
}else{
JOptionPane.showMessageDialog(null,"not recognized","command: " + command,JOptionPane.WARNING_MESSAGE);
//System.out.println("no bueno");
//System.out.println("line is " + command);
command = "";
}
}
}
Edit: For some reason when debugging, command is just blank no matter what after it's been used once, so it might be in my main server class:
package MyClient;
import java.util.List;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Main {
//Sets the Port
final static int PORT = 7591;
//Creates a list of Connected Clients
static List<Socket> connectedClients = new ArrayList<Socket>();
public static void main(String[] args){
//Creates a Thread to Send Messages to connectedClients
new Thread(new messageThread()).start();
try {
//Creates the ServerSocket
ServerSocket serverSocket = new ServerSocket(PORT);
while(true){
//Waits for a Connection and Accepts it...
Socket clientSocket = serverSocket.accept();
System.out.println("A Client has connected!");
//Adds it to the List
connectedClients.add(clientSocket);
}
} catch (IOException e) {
e.printStackTrace();
}
} }
and the messageThread:
package MyClient;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class messageThread implements Runnable {
public void run() {
while(true){
System.out.println(">>");
Scanner in = new Scanner(System.in);
String command = in.nextLine();
for(Socket clientToSendCommand : Main.connectedClients){
try {
PrintWriter commandWriter = new PrintWriter(clientToSendCommand.getOutputStream());
commandWriter.println(command);
commandWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
This dosen't work, because th line
static String command = (Main.line).toString();
in the Commands-class is executed exactly once, when the Commands-class is first referenced.
When the second command is send, the class was already referenced, so this line is not executed again.
To solve this put the line inside the method, or - much better - pass it as a parameter to the method.
P.S.: Have you mixed up the packages? The class with the ServerSocket should be the server and thus be in the MyServer package. :-)

Shifting from blocking to non-blocking I/O with javanio

i adapt this code How to send and receive serialized object in socket channel my real time simulation to send objects but i am running into exceptions one after another is it because this code blocking in nature how this code can be converted in to non blocking with javanio
/*
* Writer
*/
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class CleanSender implements Runnable {
private SimManager SM;
private BallState ballState = new BallState(10, 5);
private ServerSocketChannel ssChannel;
private Thread tRunSer = new Thread(this, "ServerSelectThread");
public static void main(String[] args) throws IOException {
CleanSender server = new CleanSender();
server.startServer();
}
private void startServer() throws IOException {
ssChannel = ServerSocketChannel.open();
ssChannel.configureBlocking(true);
int port = 2345;
ssChannel.socket().bind(new InetSocketAddress(port));
// SM = new SimManager(this, BS);
// SM.start(); // GameEngine thread starting here
tRunSer.start();
}
public void run() {
try {
SocketChannel sChannel = ssChannel.accept();
while (true) {
ObjectOutputStream oos = new ObjectOutputStream(sChannel
.socket().getOutputStream());
oos.writeObject(ballState);
System.out.println("Sending String is: '" + ballState.X + "'" + ballState.Y);
oos.close();
System.out.println("Sender Start");
System.out.println("Connection ended");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client: which is continously looking for reply from server
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;
public class CleanReceiver implements Runnable {
private SocketChannel sChannel;
private Thread receiverThread = new Thread(this, "receiverThread");
private synchronized void startServer() throws IOException {
sChannel = SocketChannel.open();
sChannel.configureBlocking(true);
if (sChannel.connect(new InetSocketAddress("localhost", 2345))) {
receiverThread.start();
}
}
public void run() {
while (true) {
try {
ObjectInputStream ois = new ObjectInputStream(sChannel.socket()
.getInputStream());
BallState s = (BallState) ois.readObject();
System.out.println("String is: '" + s.X + "'" + s.Y);
ois.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("End Receiver");
}
}
public static void main(String[] args)
throws IOException, ClassNotFoundException {
CleanReceiver rc=new CleanReceiver();
rc.startServer();
System.out.println("End Receiver");
}
}
Will this design work in the scenario when server has to keep connect the client and simultaneous send the simulation state to already connected client?, i m looking for experts glance.
thanks,
jibbylala
If you are using ObjectInputStream or ObjectOutputStream I suggest you stick with blocking IO. Using non-blocking IO with these libraries is 10x harder for no real benifit.
Have you considered using ServerSocket and Socket instead of NIO. These will be easier to use and what the object streams were originall designed to use,
Your code have two main problems:
You close streams after handling every single object, that causes closing of the associated sockets, so they are no longer valid and cannot be used for processing the following objects. At the receiving side you don't need close() inside a loop at all, at the sending side use flush() instead of close() to ensure that buffers are flushed.
When implementing blocking IO you (usually) need to start a new thread on the server for each client. It would allow you to communicate with multiple clients simultaneously. Beware of thread synchronization problems in this case!
If having a thread per client is not acceptable for you, you can implement server in a non-blocking way, but, as already said by Peter Lawrey, it's more complex, so I suggest you to get it working with blocking IO first.

Categories

Resources