Java 为什么我的程序关闭时不打印堆栈跟踪或异常?

Java 为什么我的程序关闭时不打印堆栈跟踪或异常?,java,rsa,inputstream,outputstream,Java,Rsa,Inputstream,Outputstream,出于某种原因,当我加载程序时,它会立即关闭——加载顺序是RunServer.java>Main.java。它是一个加密的消息传递应用程序,只有当客户端或服务器接收到消息时,我才尝试解密消息 我知道这是一个愚蠢的代码量,但我不能进一步压缩它,因为我似乎无法复制错误在其他任何地方后6天+试图让它工作在一个较小的模型。非常感谢您的帮助。谢谢 编辑:好的,我发现这肯定与客户机类中的bigIntegrasModPow变量有关 编辑:它与客户端类方法“whileChatting()”中的调用有关。现在我得到

出于某种原因,当我加载程序时,它会立即关闭——加载顺序是RunServer.java>Main.java。它是一个加密的消息传递应用程序,只有当客户端或服务器接收到消息时,我才尝试解密消息

我知道这是一个愚蠢的代码量,但我不能进一步压缩它,因为我似乎无法复制错误在其他任何地方后6天+试图让它工作在一个较小的模型。非常感谢您的帮助。谢谢

编辑:好的,我发现这肯定与客户机类中的bigIntegrasModPow变量有关

编辑:它与客户端类方法“whileChatting()”中的调用有关。现在我得到了一个NullPointerException,我不确定它来自哪里

Main.java

    import javax.swing.JFrame;
    import java.math.BigInteger;

    public class Main {
        public static void main(String[] args) {
            assignValues();

            client();
        }
    // Methods for the Main class //

    // Method for giving values to each variable needed for the encryption algorithm //
    private static void assignValues() {
        RSAEncryption rsa = new RSAEncryption();
        // Prompts the user for their desired bit length of keys //
        rsa.setBitLengthDefault();
        // Sets the values of the two prime keys that will be used for our encryption //
        rsa.setPrimeP(rsa.getBitLength());
        rsa.setPrimeQ(rsa.getBitLength());
        // Sets the value of prime p totient //
        rsa.setPrimePTotient(rsa.getPrimeP());
        // Sets the value of prime q totient //
        rsa.setPrimeQTotient(rsa.getPrimeQ());
        // Sets the value of e //
        rsa.setE(); 
        // Sets the value of d //
        rsa.setD(rsa.getE(), rsa.getPrimeP(), rsa.getPrimeQ());     
        // Sets the value of pq //
        rsa.setPQ(rsa.getPrimeP(), rsa.getPrimeQ());    
    }

    // Method that connects to the server and launches a client JFrame //
    private static void client() {
        // Instantiates the Client class, with the local IP address (This should be changed when in actual use) //
        Client client = new Client("127.0.0.1");

        // Sets up the default close situation (Which is when the JFrame is closed by the user) //
        client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Starts the running of the Client class as a thread //
        client.startRunning();
    }
}
Server.java

import java.io.*;
import java.math.BigInteger;
import java.net.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class Server extends JFrame {
     private JTextField userText;
     private JTextArea chatWindow;
     private ObjectOutputStream output;
     private ObjectInputStream input;
     private ServerSocket server;
     private Socket connection;

// Constructor for the Server sub-class //
public Server() {
    // Sets the title of the window //
    setTitle("Samuels Encryption Server Service");

    // Generates a new JTextField //
    userText = new JTextField();

    // Sets the JTextField to be un-editable //
    userText.setEditable(false);

    // Adds an action listener //
    userText.addActionListener(new ActionListener(){
        // Detects if the action is performed //
        public void actionPerformed(ActionEvent event){
            // Sends message with the contents of the action command //
            sendMessage(event.getActionCommand());

            // Sets the text field to empty //
            userText.setText("");
        }
    });
    // Adds the userText and sets the border layout to north of the screen //
    add(userText, BorderLayout.NORTH);

    // A new JTextArea is now instantiated //
    chatWindow = new JTextArea();

    // Adds the new JScrollPane, using the chatWindow variable and setting the border layout to center of the screen //
    add(new JScrollPane(chatWindow));

//      Use this to gain the full dimensions of the users screen //
//      Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
//      int width = (int) screenSize.getWidth();
//      int height = (int) screenSize.getHeight();

    // Sets the size of the whole window //
    setSize(325,375);

    // Sets visibility of the Swing components to true //
    setVisible(true);
}

// Starts the Server class // 
public void startRunning() {
    BasicMethods bsc = new BasicMethods();
    try {
        // Instantiates the server with port '6789' and allows 100 users to queue //
        server = new ServerSocket(6789, 100);
        while(true) {
            try {
                // Waits for a user to connect //
                waitForConnection();

                // Sets up the i/o streams //
                setupStreams();

                // Sets up the GUI to read the input stream //
                whileChatting();
            } catch(EOFException eofException) {
                // If an EOFException is given to the program, then this message is shown //
                showMessage("\nThe server has ended the connection.");
            } finally {
                // Closes the streams and makes sure the text fields are un-editable //
                closeEverything();
            }
        }
    } catch(IOException ioException) {
        // If an IOException is given to the program, then the stack trace is printed to the console //
        ioException.printStackTrace();
    }
}

// Method that waits for a user to connect to the server //
private void waitForConnection() throws IOException {
    showMessage("Waiting for another user to connect...");
    // Accepts any connection that the server receives //
    connection = server.accept();
    showMessage("\nYou have connected to " + connection.getInetAddress().getHostName());
}

// Sets the streams up in preparation for data to be sent //
private void setupStreams() throws IOException {
    // Sets up the output stream //
    output = new ObjectOutputStream(connection.getOutputStream()); 

    // Flushes spare bytes out of the Client machine //
    output.flush();

    // Sets up the input stream //
    input = new ObjectInputStream(connection.getInputStream());

    showMessage("\nStreams are now setup!");
}

// Method that is run whilst the users are connected to each other //
private void whileChatting() throws IOException {
    String message = "You are now connected!\n";
    sendMessage(message);
    // Sets the chat box to be editable //
    ableToType(true);
    do {
        try {
            message = (String) input.readObject();
        //  RSAEncryption rsa = new RSAEncryption();

        //  BigInteger bigIntegerModPow = new BigInteger(message).modPow(rsa.getD(), rsa.getPQ());

            showMessage("\n" + new String(message));
        } catch(ClassNotFoundException classNotFoundException) {
            showMessage("\nThe server is unable to understand that String.");   
        }
    } while(!message.equals("Client : END CONNECTION"));
}

// Method that sends a message using the output stream //
private void sendMessage(String message) {
    try {
        if (message.length() < 1 || message.length() > 50) {

        } else {
            showMessage("\nServer : " + message);

            RSAEncryption rsa = new RSAEncryption();

            rsa.setPrimeP(1024);
            rsa.setPrimeQ(1024);

            BigInteger p = rsa.getPrimeP();
            BigInteger q = rsa.getPrimeQ();

            rsa.setE();
            rsa.setPQ(p, q);

            BigInteger e = rsa.getE();
            BigInteger pq = rsa.getPQ();

            byte[] messageAsBytes = message.getBytes();

            BigInteger bigIntegerModPow = new BigInteger(messageAsBytes).modPow(e, pq);

            output.writeObject("Server : " + bigIntegerModPow);
            // Flushes the output stream //
            output.flush();
        }
    } catch(IOException ioException) {
        // If an IOException is given to the program, then this message is printed to the console //
        chatWindow.append("\nERROR CODE : 0");

        ioException.printStackTrace();
    } 
}

// Method that does not allow the user to type to the text box and closes the i/o streams //
private void closeEverything() {
    showMessage("\nClosing connections...\n");
    // Sets the text box to be un-editable //
    ableToType(false);
    try {
        // Closes the output stream //
        output.close();

        // Closes the input stream //
        input.close();

        // Closes the connection between Client and Server //
        connection.close();
    } catch(IOException ioException) {
        // If an IOException is given to the program, then the stack trace is printed to the console //
        ioException.printStackTrace();
    }
}

// Method that prints a message to the text field //
private void showMessage(final String text) {
    // Invokes a new runnable //
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            // Appends the message to the chat window //
            chatWindow.append(text);
        }
    });
}

// Method that deals with permissions of the text field //
private void ableToType(final boolean tof) {
    SwingUtilities.invokeLater(new Runnable() {
        // Invokes a new runnable //
        public void run() {
            // Sets the userText field to be editable (depending on the input of the function //
            userText.setEditable(tof);
        }
    });
}
}
import javax.swing.JFrame;

public class RunServer {
public static void main(String[] args) {
    Server server = new Server();
    server.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    server.startRunning();
}
}
BasicMethods.java

public class BasicMethods {
// Method to print to the console in white text // 
public void println(Object x) {
    System.out.println(x);
}

// Method to print to the console in red text //
public void errorPrintln(Object x) {
    System.err.println(x);
}

// Method to exit the program and return 0 // 
public void exit(int x) {
    System.exit(x);
}
}

这可能与对System.exit()的调用有关,这会杀死整个JVM,从而破坏堆栈的内容。

使用调试器逐步完成它。所有分散在代码中的
exit()
调用是怎么回事?这是非常糟糕的做法。因此,我删除了所有exit()调用。我可以问一下,为什么它被列为坏习惯?当然,它会停止程序中的所有进程,因此一旦程序完成,就不需要垃圾收集器仍然在周围寻找要清理的东西等等,请在第一个字上加上更大的强调。我已经提到,我不能缩小它的大小。我不希望人们阅读所有这些内容,但我无法减少这些内容并保留错误。我已完成删除所有System.exit()调用。但是保留了方法。不要猜测答案。诚然,如果达到该值,调用
System.exit()
确实会关闭整个JVM,但这需要
Client.startRunning()
立即返回,而这似乎不是它想要的。
import javax.swing.JFrame;

public class RunServer {
public static void main(String[] args) {
    Server server = new Server();
    server.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    server.startRunning();
}
}
public class BasicMethods {
// Method to print to the console in white text // 
public void println(Object x) {
    System.out.println(x);
}

// Method to print to the console in red text //
public void errorPrintln(Object x) {
    System.err.println(x);
}

// Method to exit the program and return 0 // 
public void exit(int x) {
    System.exit(x);
}
}