0

I'm attempting to send a message to a server using sockets. I'm using a Runnable and getting the following error:

W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.OutputStream java.net.Socket.getOutputStream()' on a null object reference
W/System.err:     at XXX.FullscreenActivity.attemptConnect(FullscreenActivity.java:387)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:270)
W/System.err:     at android.view.View.performClick(View.java:5198)
W/System.err:     at android.view.View$PerformClick.run(View.java:21147)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:739)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err:     at android.os.Looper.loop(Looper.java:148)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5417)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
W/System.err: ERROR: Attempt to invoke virtual method 'java.io.OutputStream java.net.Socket.getOutputStream()' on a null object reference

This is the line I'm getting the error on:

PrintWriter out = new PrintWriter(new BufferedWriter(
                        new OutputStreamWriter(clientsocket.getOutputStream())),
                        true);

The full code of the connection code is:

EditText editTextAddress = (EditText) findViewById(R.id.address);
EditText editTextPort = (EditText) findViewById(R.id.port);
SERVER_IP_loc = editTextAddress.getText().toString();
SERVERPORT_loc = Integer.parseInt(editTextPort.getText().toString());
System.out.println("AttemptConnect: IP " + SERVER_IP_loc +
    " Port: " + SERVERPORT_loc);
Thread myTask = new Thread(new ClientThread(SERVER_IP_loc, SERVERPORT_loc));
myTask.start();
final String message = "CONNECT";
try{
PrintWriter out = new PrintWriter(new BufferedWriter(
                        new OutputStreamWriter(clientsocket.getOutputStream())),
                        true);
}
catch (Exception e) {
    e.printStackTrace();
    System.err.println("ERROR: " + e.getMessage());
}

The socket is apparently null, but I can't figure out why. I'm starting the socket before attempting to send the message. The ClientThread code is a runnable:

class ClientThread implements Runnable {
    ClientThread(String addr, int port) {
        System.out.println("IN CLIENT THREAD");
        SERVER_IP = addr;
        SERVERPORT = port;
        testMainThread(8);
    }
    @Override
    public void run() {
        testMainThread(9);
        try {
            InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
            System.out.println("RUN2");
            if(Looper.getMainLooper().getThread()==Thread.currentThread()) {
                System.out.println("in main thread, don't make socket.");
            }
            else {
                System.out.println("not in main thread, make socket.");
                try {
                    clientsocket = new Socket(serverAddr, SERVERPORT); 
                }catch (Exception e3) {
                    e3.printStackTrace();
                }
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
}
interplex
  • 277
  • 1
  • 2
  • 8
  • Where you are using `clientsocket.getOutputStream()` line? – ρяσѕρєя K Feb 01 '16 at 02:30
  • Java is not a scripting language and this is not a script. *Obviously* `clientSocket` is still `null`. – user207421 Feb 01 '16 at 02:33
  • Edited the question. It's right after the connection code. – interplex Feb 01 '16 at 02:33
  • You should do the I/O in the thread as well as the connection. You're calling `getOutputStream()` before the connection thread has got to the part where it creates the socket. – user207421 Feb 01 '16 at 02:35
  • @EJP In that case, wouldn't I need every message being sent to be sent on that thread? That solution seems fine for one message but I have multiple. – interplex Feb 01 '16 at 02:38
  • Maybe, or a separate sending thread. Just doing the connect alone on a thread doesn't make sense, especially if you don't notify yourself about completion and just assume it worked. – user207421 Feb 01 '16 at 02:49
  • That's what I was trying to do, use ClientThread as a sending thread. I was under the assumption that opening the socket on that thread would do that, but I guess not. So if I have a message sending function, would I need to tell that to operate only on the sending thread? Presumably by putting it in as a function of ClientThread? – interplex Feb 01 '16 at 02:52
  • Opening a socket on that thread opens the socket. It doesn't magically cause all I/O to happen on that thread. You are getting the output stream in the thread that starts that thread, not the thread that opens the socket. And over-running yourself. If you already have a message-sending function I don't see any need to disturb it, and 'putting it as a function of `ClientThread` won't fix anything, but both it and the construction of the `PrintWriter` must wait until the socket has been connected. Personally I would get rid of the connection-creating thread and do it inline. – user207421 Feb 01 '16 at 03:01
  • The connection creating thread is the UI thread for the app, so I can't do the network operations on that. I tried adding a couple of lines to make sure it waited until clientsocket was not null, but that didn't help the problem. Neither does moving the message sending function to ClientThread, which just creates a whole bunch of separate problems with not being able to call it. – interplex Feb 01 '16 at 03:14
  • So you can't call `getOutputStream()` in that thread either, at least until you've actually created the socket, and you can't wait in this thread either. You have a code-organization problem here. You need to at least move the construction of the `PrintWriter` into the connect thread, and somehow delay all output to that socket until the socket and `PrintWriter` actually exist. I can't advise you on Android program structure but you have to clean it up. – user207421 Feb 01 '16 at 03:21
  • That fixed it. Thanks. – interplex Feb 01 '16 at 03:47

0 Answers0