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: setSocketreturning directly a single instance ofMySocketand 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 doStreamon thenotifyDatamethod. This works, but it shouldn't be necessary asdoStreamshould 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?
