Вопрос

I am working on a simple server in Java that should have a capability of transferring a file across computers. I am getting a NullPointerException on line 77 of Protocol.class. Here is the stack:

java.lang.NullPointerException
       at Protocol.processInput(Protocol.java:77)
       at Server.main(Server.java:41)

Why does this happen? There is no null references on line 77!

Client.java:

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;


public class Client {

    private static boolean filein = false;
    private static ArrayList<String> fln = new ArrayList<>();

    public static void main(String[] args) throws IOException {

        if (args.length != 2) {
            System.err.println(
                "Usage: java Client <host name> <port number>");
            System.exit(1);
        }

        String hostName = args[0];
        int portNumber = Integer.parseInt(args[1]);

        try (
            Socket kkSocket = new Socket(hostName, portNumber);
            PrintWriter out = new PrintWriter(kkSocket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(
                new InputStreamReader(kkSocket.getInputStream()));
        ) {
            BufferedReader stdIn =
                new BufferedReader(new InputStreamReader(System.in));
            String fromServer;
            String fromUser = null;

            while ((fromServer = in.readLine()) != null) {
                System.out.println("Server: " + fromServer);
                if (fromServer.equals("@file")) { filein = true; 
                fromUser = "";}
                else if(fromServer.equals("@end@")) {

                    filein = false;
                    JFileChooser chooser = new JFileChooser();
                    int returnVal = chooser.showSaveDialog(null);
                    if(returnVal == JFileChooser.APPROVE_OPTION) {
                           String fname = chooser.getSelectedFile().getAbsolutePath();
                           File f = new File(fname);
                           f.createNewFile();
                           PrintWriter p = new PrintWriter(f);
                           for(int i = 0; i < fln.size(); i++) {

                               p.println(fln.get(i));

                           }

                           p.close();
                           JOptionPane.showMessageDialog(null, "File saved!");
                    }


                }
                else if (filein == true) {

                    fln.add(fromServer);
                    System.out.println(fln.get(fln.size() - 1));

                }
                if (fromServer.equals("Bye."))
                    break;

                if (!filein) fromUser = stdIn.readLine();
                else if (filein) fromUser = "@contintueFileRun";
                if (fromUser != null) {
                    System.out.println("Client: " + fromUser);
                    out.println(fromUser);
                }
            }
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host " + hostName);
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to " +
                hostName);
            System.exit(1);
        }
    }

}

Server.java:

import java.io.*;
import java.net.*;

import static java.lang.System.out;

/**
 * Title: FTP Server
 * @author Galen Nare
 * @version 1.0
 */

public class Server {
    public static void main(String[] args) throws IOException {

        out.println("Starting server!");

        if (args.length != 1) {
            System.err.println("Usage: java Server <port number>");
            System.exit(1);
        }

        int portNumber = Integer.parseInt(args[0]);

        try ( 
            ServerSocket serverSocket = new ServerSocket(portNumber);
            Socket clientSocket = serverSocket.accept();
            PrintWriter out =
                new PrintWriter(clientSocket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(
                new InputStreamReader(clientSocket.getInputStream()));
        ) {

            String inputLine, outputLine;

            // Initiate conversation with client
            Protocol kkp = new Protocol();
            outputLine = kkp.processInput("");
            out.println(outputLine);

            while ((inputLine = in.readLine()) != null) {
                outputLine = kkp.processInput(inputLine);
                out.println(outputLine);
                if (outputLine.equals("Bye."))
                    break;
            }
        } catch (IOException e) {
            System.out.println("Exception caught when trying to listen on port "
                + portNumber + " or listening for a connection");
            System.out.println(e.getMessage());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

And finally, Protocol.java:

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

public class Protocol {

    enum ServerState {

        STARTING,
        WAITING

    }  

    ArrayList<String> lns;

    boolean fileout = false;
    int i = 0;

        private ServerState state = ServerState.STARTING;

        public String processInput(String theInput) throws Exception {
            String theOutput = "";

            if (state == ServerState.STARTING) {
                theOutput = "Hello, Client!";
                state = ServerState.WAITING;
            }

            if (!theInput.equals("")) {
                if(theInput.length() > 10 && theInput.startsWith("e")) {
                if (theInput.substring(0,11).equalsIgnoreCase("executecmd ")) {
                theOutput = theInput.substring(11);
                System.out.println(theOutput);
                 try {
                    @SuppressWarnings("unused")

                    Process child = Runtime.getRuntime().exec(theInput.substring(11));
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                theOutput = "Executed " + theInput.substring(11) + ".";
                }
            } else if (theInput.equalsIgnoreCase("stop")) {

                theOutput = "Stopping Server!";
                System.exit(0);

            } else if (theInput.equalsIgnoreCase("executecmd")) {

                theOutput = "Usage: executecmd <command [-options]>";


            } else if (theInput.equalsIgnoreCase("getfile")) {

                theOutput = "Usage: getfile <file>";

            } else if(theInput.length() > 7 && theInput.startsWith("g")) {
                System.out.println("in");
                if (theInput.substring(0,8).equalsIgnoreCase("getfile ")) {
                theOutput = theInput.substring(8);
                File f = new File(theInput.substring(8));
                Scanner scan = new Scanner(f);
                ArrayList<String> lns = new ArrayList<>();
                while(scan.hasNext()) {
                    lns.add(scan.nextLine());
                }
                for (int i=0; i < lns.size(); i++) {
                    System.out.println(lns.get(i));
                }
                scan.close();
                lns.add("@end@");
                theOutput = "@file";
                fileout = true;
                }
            } else if (fileout && i < lns.size()) {

                    theOutput = lns.get(i);
                    i++;

            } else if (fileout && i == lns.size()) {

                i = 0;
                fileout = false;

            } else {


                theOutput = "That is not a command!";

            }


            }
            System.out.print(theOutput);
            return theOutput;
     }
}

Thanks in advance!

Это было полезно?

Решение

You're never initializing lns in Protocol, so it's always a null reference. You may be able to get away with just changing the declaration to:

private List<String> lns = new ArrayList<String>();

(I've made it private and changed the type to List just out of habit...)

You should also consider giving it a more readable name - is it meant to represent lines? If so, call it lines!

(Next, consider why you weren't able to diagnose this yourself. Did you step through this in the debugger? Why did you think there were no null references on line 77? What diagnostic steps did you take in terms of adding extra logging etc? It's important to use errors like this as a learning experience to make future issues more tractable.)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top