Disclaimer: Before anyone marks this a duplicate of What is a NullPointerException, and how do I fix it?, I know what a NullPointerException is and how to fix it. This concrete NullPointer, for some reason after a few hours I can't fix.
So, I have a simple socket class where I create my socket and send two Hello as a test:
package network.outgoing;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
public class MySocket extends Thread{
private Socket socketServer;
private DataOutputStream doStream;
private DataInputStream diStream;
private final int PORT;
public MySocket(int port) {
this.PORT = port;
}
public void run() {
InetAddress iAddress;
try {
iAddress = InetAddress.getLocalHost();
String ip = iAddress.getHostAddress();
socketServer = new Socket(ip, PORT);
doStream = new DataOutputStream(socketServer.getOutputStream());
diStream = new DataInputStream(socketServer.getInputStream());
doStream.writeUTF("Hello, I'm " + Node.name);
doStream.writeUTF("Hello 2");
} catch (Exception e) {
e.printStackTrace();
}
}
public void notifyData(String operation, String name) {
try {
doStream.writeUTF("OPERATION"); //NullPointerException
doStream.writeUTF(operation);
} catch (IOException e) {
e.printStackTrace();
}
}
}
I need several instances of this class, so in my main controller I have an array where I store them:
private final ArrayList<MySocket> socketListA;
which is initialized in the constructor:
socketListA = new ArrayList<>(); // only place where a new is called on socketListA
setSockets(ports, myPort);
in the setSockets
method (a simplified version removing other innecessary stuff):
for (int port : ports) {
MySocket mySocket = new MySocket(port); // only place where a new is called on MySocket
mySocket.start();
socketListA.add(mySocket);
}
Creating and starting the MySocket
thread sends correctly the two test Hello from the run
method, but accessing it from the array as such:
socketListA.get(random.nextInt(socketListA.size() - 1)).notifyData(line, name);
gives null pointer on the doStream
inside the notifyData
method.
I tested several things:
- Not using the arrayList:
setSocket
returning directly a single instance ofMySocket
and trying adoStream
(set to public for this test) from the returned instace, but it's null: - Checked if the instance in the arrayList, is the same as the one created and stored in it (with both hash and equals) and yes, they are the same (not accessing an invalid or different instance when calling
notifyData
). Same check was done in the previous point for the returned instance ofMySocket
- Created (again) a
doStream
on thenotifyData
method. This works, but it shouldn't be necessary asdoStream
should have a value.
Note: The socketListA
arrayList is created only once, and the MySocket
instance is created also once.
Why is the doStream
in notifyData
null, if it has been created in the run
method and the instance of the class is the same?