java.lang.NullPointerException PrintWriter - java

I am getting a NullPointerException when I run my code. I have narrowed down the problem to line 38: when it is commented out the program doesn't give any errors. I just have "test" here for now.
out.println("test")
The run method is immediately started with the following two lines in another class
Client test = new Client();
test.start();
And when a button is pressed the following code is executed which runs the sendToServer method
Client test = new Client();
test.sendToServer(cipherText)
Below is the full code for my Client class.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Client extends Thread{
String line = "";
String cipherText = "";
BufferedReader in;
PrintWriter out;
public void run(){
String serverAddress = "00.000.000.000";
try{
Socket socket = new Socket(serverAddress, 8888);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
}
catch(IOException e){
e.printStackTrace();
}
while (true) {
try{
line = in.readLine();
}
catch(IOException e){
e.printStackTrace();
}
System.out.println(line);
}
}
public void sendToServer(String in) {
out.println("test");
}
}
Thanks for looking, I am still learning java so excuse any obvious mistakes.

You have in the beggining of the class:
PrintWriter out;
if you don't call run() [is where you initialize it] before sendToServer(), "out" would never be initialized and will be null.

That is because you have used PrintWriter out; as your class member but you have not initialized it. By default, all un-initialized member objects are initialized with null. If sendToServer() is called first, out will be null and you will get NullPointerException.
EDIT
Problem is that you are trying to invoke run() and sendToServer() methods on two separate instances of Client.
Client test = new Client(); // First instance
test.start(); // which calls run() and then initializes out variable.
Then a second instance is created from:
Client test = new Client(); // Second instance
test.sendToServer(cipherText); // since out is not initialized for this instance, you are getting NPE
I suppose you are using Client object in a multi-threaded environment, in that case I would suggest you to make sure that both threads are using same instance of Client object. Also if Client instance is being shared, you might want to make access to out variable synchronized and also make sure that Client's run method is executed first before button is pressed (which in turn calls sendToServer()).

Your function assumes out Printwriter will be initialized, but if there is an exception in the socket initialization, it will never by initialized. Two things I would do...
1. Initialize out to null at the top of the run method.
2. protect your sendToServer code...
public void sendToServer(String in) throws NullPointerException
{
if (out == null)
{
throw new NullPointerException("Out is null.");
}
out.println("test");
}

Related

IllegalThreadStateException Error on Simple Chat Application using Socket Programmin, Code bellow

Client code:
import java.io.BufferedReader;
import java.io.IOError;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
import java.util.Scanner;
import javax.swing.*;
import java.io.*;
public class messages_client
{
static BufferedReader in;
static Scanner sc;
static PrintWriter out;
public static void main(String args[])
{
try{
JFrame frame=new JFrame();
Socket client=new Socket("localhost",59001);
in=new BufferedReader(new InputStreamReader(client.getInputStream()));
out=new PrintWriter(client.getOutputStream(),true);
sc=new Scanner(System.in);
boolean running=false;
String input=in.readLine();
System.out.println(input);
String name=sc.next();
out.println(name);
running=true;
Thread send=new Thread(new send());
Thread recieve=new Thread(new recieve());
if(running == true)
{
while(true)
{
send.start();
recieve.start();
}
}
} catch(IOException e){}
}
public static class send implements Runnable
{
#Override
public void run()
{
String message=sc.nextLine();
out.println(message);
}
}
public static class recieve implements Runnable
{
#Override
public void run()
{
try {
String input=in.readLine();
System.out.println(input);
} catch (IOException e) {
}
}
}
}
Server code:
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.Executors;
public class messages_server
{
private static ServerSocket server;
private static Set<PrintWriter> printwriters=new HashSet<>();
public static void main(String args[])
{
try{
server=new ServerSocket(59001);
var pool=Executors.newFixedThreadPool(5);
System.out.println("Server is running");
while(true)
{
pool.execute(new ClientHandler(server.accept()));
}
} catch(IOException e)
{
} finally
{
try{
server.close();
} catch(IOException e){}
}
}
private static class ClientHandler implements Runnable
{
private Socket client;
private static PrintWriter out;
private static BufferedReader in;
private static String message;
private static String name;
ClientHandler(Socket client)
{
this.client=client;
}
#Override
public void run()
{
try{
out=new PrintWriter(client.getOutputStream(),true);
in=new BufferedReader(new InputStreamReader(client.getInputStream()));
send("Name: ");
name=in.readLine();
System.out.println(name);
out.println("1");
broadcast(name+" has joined the chat");
while(true)
{
message=in.readLine();
broadcast(name+":"+message);
}
} catch(IOException e){}finally
{
if(in != null)
{
printwriters.remove(out);
broadcast(name+" has left the chat");
}
try{
client.close();
}catch(IOException e){}
}
}
public void broadcast(String message)
{
for(PrintWriter printwriter:printwriters)
{
printwriter.println(message);
}
}
public void send(String message)
{
out.println(message);
}
}
}
I have created this simple Chat Application where multiple users can join a common chat.The Server creates a different thread for each client and continuously recieves and broadcasts data.The client to has two threads: "send" "recieve" which send and recieve data continuosly.
The Server works fine but when I run the client after typing in my name there shows IllegalThreadStateException.
Please help and suggest if there is anyway I can improve this code too.
I think you're confused about what Thread's start() method does.
In your code:
Thread send = new Thread(new send());
Thread recieve = new Thread(new recieve());
You create exactly one thread (send) for sending, and exactly one (recieve - note you have a typo, it's "receive". English is weird) for receiving.
You then:
while(true)
{
send.start();
recieve.start();
}
repeatedly (while loop) invoke .start() on these single threads.
That's not how it works: You can only start a Thread object once, ever. If you invoke .start() the second time, you get IllegalThreadStateException, because the state is 'STARTED' and you can't call .start() on such a thread.
What's not quite clear is your intent. Were you intending to continually start threads? Then you'd have to create a new thread object every time and then start it, i.e. move the Thread send = ...; code inside the while loop. However, I can't imagine you want that: If you stick that in a while(true) the system will create an infinite amount of threads, starts them, and, naturally, crashes very very quickly and very definitely if you try that.
If your intent is simply to keep that one send and one receive thread from continuing to run - there is no need to repeatedly invoke .start() or do anything else from the main method - your receive and send runnables already have loops (they both have a while(true) loop of their own).
If you intent is to restart any thread that somehow stopped itself, 'just in case' - that's not how it works. Once a thread ends you can't start it again - you'd have to make a new one. And as discussed before, just making an endless amount of threads is just going to lead to a swift crash. You CAN ask a thread if it is no longer running, and then create a new thread and start the new one, but you shouldn't defensively program.
Let me clarify that, because the term 'defensive programming' is overloaded: You should not write code to deal with situations that are not understood. In this case, the situation is: "I dont quite know how, but lets just imagine the send thread is somehow stopped. I want to restart it if this happens". The reason that kind of defensive programming is bad, is: By definition you don't really know what happened (after all, you have no idea how some state COULD happen, therefore it is likely that you're missing rather crucial understanding about what's going on when the to you impossible situation does evidently occur), so the odds that you're doing the right thing (that 'just restart it' is the right answer to 'huh, weird, that thread stopped and I do not understand why') are low.
Most likely, the situation you can't fathom happening can, in fact, never happen, so you wrote a bunch of code that never ever runs. This leads to the biggest problem of defensive programming: The code is untestable, and rarely (often never) runs, which means any bugs in it go completely unnoticed. So you now have useless code that if it ever becomes useful, doesn't work at all.
It is FAR better to just hard-crash out with an exception in such impossible cases. At least then, if it does occur, you have a lead on investigating. Only after you understand can you write code that deals with the situation.

ArrayList empty when accessed from separate thread although it is populated.

I have a simple Client/Server Application. I try to access the arraylist from UI but get an empty arraylist in return. I have tried every possible solution on internet but none has worked in my case.
Server.java
import java.net.*;
import java.util.ArrayList;
import java.io.*;
public class Server {
public static ArrayList<MyThread> clients = new ArrayList<MyThread>();
public static void main(String args[]) throws IOException {
ServerSocket s = new ServerSocket(7777);
try {
while (true) {
Socket s1 = s.accept();
MyThread t = new MyThread(s1);
clients.add(t); // adds threads to an ArrayList
System.out.println(clients); // prints the ArrayList(It works and print all threads)
t.start(); //start the thread
}
} catch (SocketException e) {
System.out.println("Error: " + e);
}
}
}
This is a MouseClickeed method in my UI class where I want to access the ArrayList in Server Class
public void mouseClicked(MouseEvent arg0) {
try {
String s = textField.getText();
Client.ClientName = s; \\ gets the string entered and set it as Client Name
System.out.println(Server.clients); \\It's supposed to print Client ArrayList but instead it prints an empty List ([])
}
catch (NullPointerException e1) {
System.out.println("Error: " + e1);
}
}
});
It's look like you try to use objects from Server application in client application with UI.
Server and client app are two different processes.
Server.clients is initialized with values in your server app, and isn't initialized in your client app.
You're not just working with separate threads, you're working with different processes.
The Server process has it's own Server.class instance. The Client is launched in a different java process, it could use the same classes, but they will be different instances, even the static fields will be different in different processes.
If you need data from the Server in the Client, you need some sort of communication. You already have tcp/ip socket, so you could send the list via the socket.
Or you could use some distributed cache library if you want to use this pattern in a large application. E.g. hazelcast or Terracotta DSO

Can not access object's properties(methods) from within the run method! Java Multithreading

I have the following code in ServerConnectionManager:
public class ServerConnectionManager implements Runnable {
private DatagramPacket receivedPacket;
//some more things here
public ServerConnectionManager(DatagramPacket receivedPacket){
this.receivedPacket = receivedPacket;
System.out.println("Connection manager has been assigned a request");
System.out.println("The port of the request packet is "+receivedPacket.getPort());
try {
sendReceiveSocket = new DatagramSocket();
} catch (SocketException se) {
se.printStackTrace();
System.exit(1);
}
}
#Override
public void run() {
//DEBUGGING LINES HERE
System.out.println("The start method on connection manager works..");
System.out.println("Point A");
System.out.println("The port of the request packet is "+receivedPacket.getPort()); // the thread gets stuck here
System.out.println("Does this work..?"); //This line never gets printed
//some other stuff to be done here
}
}
And i have some code in the run method of some other threads that make use of ServerConnectionManager: Lets Call this Thread B
#Override
public void run() {
while(true){
try {
System.out.println("Waiting..."); // so we know we're waiting
receiveSocket.receive(receivePacket);
} catch (IOException e) {
System.out.print("Stopped Listening for some reason..");
//e.printStackTrace();
}
System.out.println("Server received something" );
//Constructor of ServerConnectionManager
ServerConnectionManager serverConnectionManager = new ServerConnectionManager(receivePacket);
Thread managerThread = new Thread(serverConnectionManager, "connectionManager ");
managerThread.start();
//some more stuff to be done
}
}
The problem is that I can not call any methods on receivedPacket from within ServerConnectionManager run method. However, I am able to call receivedPacket.getPort() from within the constructor of this ServerConnectionManager thread and it gives me an expected output. But it does not do anything from within run method. The last line ServerConnectionManager prints is "Point A". Nothing after that!! Please check my DEBUGGING comments around that area to get a better idea of what I am talking about.
I know I have provided alot of code. But I can not understand the problem at all. I have tried passing additional parameters(objects) from Thread B to the constructor of ServerConnectionManager. And I am able to access those from the run method of ServerConnectionManager. Its just the receivedPacket that does not work...
You need to create a new DatagramPacket per receive if you want to start a new thread to handle it. Otherwise one thread is synchronized on it during receive() while the other thread is trying to call getPort(). The design is invalid in any case, as the receive() will overwrite everything in the previously received datagram while the thread is trying to process it.

Threaded Java server with inner class and final variable

I've written the following code to implement a Threaded Server:
ServerSocket passiveSocket = new ServerSocket(port, maxConnections);
while(true){
final Socket socket = passiveSocket.accept();
new Thread(new Runnable() {
public void run() {
//access socket as needed to communicate. E.g.:
PrintWriter writer = new PrintWriter(socket.getOutputStream());
//Finally close socket.
socket.close();
}
}).start();
}
Now this seems to work, but in reflection I do not really understand what's going on with the final socket variable socket when the next connection arrives. How is each thread associated with the socket instance which was current when starting the thread? - is the final keyword responsible for that?
Think of it this way: socket is secretly passed as an argument to the new Runnable constructor, and it's kept as a variable in the anonymous Runnable class. (That's actually how it works, at the bytecode level.)
The created Runnable object contains a reference to the one specific Socket value at its creation time, so it can close that specific socket when it's done.
When passing a final variable to an anonymous inner class, that variable is effectively stored in the anonymous class as if it was an instance variable.
The code above could be effectively translated to:
private static final class RunnableAnonSubclass implements Runnable {
private final Socket socket;
private RunnableAnonSubclass (Object socket) {
this.socket = socket;
}
public void run() {
//access socket as needed to communicate. E.g.:
PrintWriter writer = new PrintWriter(socket.getOutputStream());
//Finally close socket.
socket.close();
}
}
// ...
{
ServerSocket passiveSocket = new ServerSocket(port, maxConnections);
while(true){
Socket socket = passiveSocket.accept();
new Thread(new RunnableAnonSubclass(socket)).start();
}
}
Notice that making a local variable final is the only way to access it inside an anonymous inner class. See Jon's answer on "Why are only final variables accessible in anonymous class?" for details on the reasons.

unreported exception java.io.IOException

What's wrong with this code
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* #author Master
*/
public class Server {
try
{
ServerSocket S = new ServerSocket(3333);
Socket So = S.accept();
}
catch(IOException e)
{
System.out.println("IOError");
}
}
Firstly I wrote the code without try catch and I got an unreported exception java.io.IOException; must be caught or declared to be thrown Error but Netbeans didn't suggest that I add a try-catch block . Now I added the try-catch block manually but It still shows an error and suggests that I must add another try-catch block !
You're trying to add a try block at the top level of the class - you can't do that. Try blocks have to be in methods or initializer blocks.
If you really want to create the server socket on construction, put the code in a constructor:
public class Server {
private ServerSocket serverSocket;
private Socket firstConnection;
public Server {
try
{
serverSocket = new ServerSocket(3333);
firstConnection = serverSocket.accept();
}
catch(IOException e)
{
System.out.println("IOError");
}
}
}
I assume you'll have real exception handling (or rethrowing) rather than just catching the IOException and continuing, of course?
This is not valid Java. This code needs to be in a block, method, or constructor.
From the screenshot of your IDE, the error "must be caught or declared to be thrown" is not the only error you have.
When you have syntax that is this far off, the compiler will likely report several errors, some of which are side-effects of other errors - like not enclosing this code in a method (I'm sure the red X next to the catch block is reporting a similar error).

Categories