I have the following piece of code. SonarLint saying socket should be closed in finally block.
But I have already closed it.
I have observed one more thing here is: I am getting this only if I have serverSocket.isClosed() condition in finally if condition. If I remove it, the issue is solved.
Here I wanna know that what is the problem with this condition becoz of that sonarLint could not recognize the socket closing.
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(5555);
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(serverSocket != null && !serverSocket.isClosed())
{
try
{
serverSocket.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
Because of the this : if(serverSocket != null &&
You are using an if statement and checking if the serverSocket in NOT NULL AND
here the problem is that is serverSocket is not null then the && operator will not let the next condition to execute and the if statement will not execute,eventually, the connection will not closed.
Related
I have defined Output stream like below
OutputStream os=new FileOutputStream(file);
Tried to close the resource like below
if(os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}}
Still sonarlint showing "Use try-with-resources or close this "FileOutputStream" in a "finally" clause."
If you are doing the operations in the same method it's important to put the close in a finally statement of a try that envolves the open part of the stream. This ensures that in case of failure (Exception) the stream is allways closed if required
Bad sonar code:
OutputStream os=new FileOutputStream(file);
... // your code operations with os
// If something is going really bad here and ends in exception the
// stream will never be closed
if(os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Better code:
OutputStream os = null;
try{
os = new FileOutputStream(file);
... // your code operations with os
} finally{
// The stream is allways closed at the end of the method execution
if(os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The best code (in case of Java 1.7 or upper)
try (OutputStream os = new FileOutputStream(file)){
... // your code operations with os
// The stream is allways closed at the end of the try block
}
Try this instead. You do not do a close when using try with resources, that is automatically handled... i.e.
"The try-with-resources statement ensures that each resource is closed
at the end of the statement."
try( OutputStream os=new FileOutputStream(file) ) {
....
}
Any resources declared within the brackets are closed automatically once the program flow has completed whether an exception is thrown or not..
Examples here : https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
I'm fairly new to sockets and using threads in this way.
I am running into a problem with a scanner waiting for user input and an input stream reader waiting for socket communication at the same time. My program is trying to communicate with a client/server system, and that works fine, however I'm also wanting to be able to input commands into the console directly via a scanner or something similar. However the main thread's while loop is blocking for socket communication, while the scanner is blocking in the inputThread's while loop.
My problem is that if I send the command in the console to close the server (sets the bool 'running' to false), the main thread's while loop still waits for socket communication input. Once it receives any message it'll escape from the while loop due to the bool 'running' being set to false, but only once any message is sent due to it waiting for one before checking the while's conditional.
My other problem is basically the same concept, but inside the inputThread's while loop. If the main thread's while loop breaks then the input thread still has the scanner blocking until it receives user input. Once it receives any user input it'll escape from the while loop due to the thread being interrupted (while loop's conditional).
So in order for my program to exit I have to send the "restart server" message via sockets and user input, when I'd like to send it either way for the program to correctly exit.
How would I solve this problem? I'd assume by cancelling the scanner's blocking when I receive the socket to end the server, but how would I do that? I feel like there's a much better way to do this, any ideas?
Code:
inputThread = new Thread(new Runnable() {
#Override
public void run() {
Logger.log("Starting input thread...");
while(!Thread.currentThread().isInterrupted()) {
try {
scanner = new Scanner(System.in);
String reply = runCommand(scanner.nextLine());
Logger.log(reply);
if(reply.equals("server restarted")) {
// TODO: Cancel socket input blocking?
}
} catch(Exception e) {
e.printStackTrace();
}
}
Logger.log("Closing input thread...");
}
});
inputThread.start();
ServerSocket socket = null;
InputStreamReader inputStream = null;
BufferedReader input = null;
try {
int port = getPort();
socket = new ServerSocket(port);
Logger.log("Server running on port " + port);
while(running) {
connection = socket.accept();
inputStream = new InputStreamReader(connection.getInputStream());
input = new BufferedReader(inputStream);
String reply = runCommand(input.readLine());
if(reply.equals("server restarted")) {
// TODO: Cancel scanner input blocking?
}
reply(reply);
}
} catch(Exception e) {
e.printStackTrace();
} finally {
if(socket != null) {
try {
socket.close();
} catch(IOException e) {
e.printStackTrace();
}
}
if(connection != null) {
try {
connection.close();
} catch(IOException e) {
e.printStackTrace();
}
}
if(inputStream != null) {
try {
inputStream.close();
} catch(IOException e) {
e.printStackTrace();
}
}
if(input != null) {
try {
input.close();
} catch(IOException e) {
e.printStackTrace();
}
}
if(response != null) {
try {
response.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
inputThread.interrupt();
Thank you for reading
The first problem is the ServerSocket::acceptcall. It is blocking, but not responsive to interruption (if it were it would be declared to throw InterruptedException). The way to unblock it immediately is to close the socket from the other thread. The accept() call will then immediately throw a SocketException.
The second problem is actually simpler to solve : the while loop should also be checking the running flag. So when a command line input is given to stop the program, the input thread doesn't start waiting for the next command.
This question already has an answer here:
readLine() loop not exiting until remote client closes connection
(1 answer)
Closed 5 years ago.
Im reading the input line by line from a socket InputStream using a BufferedReader but nothing after the while loop seems to get executed. The socket is coming from accept() on ServerSocket not from something like this Socket link = new Socket(address, 80);.
Code
String input;
BufferedReader in = null;
DataOutputStream out = null;
boolean foundConnectionHeader = false;
try {
in = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
out = new DataOutputStream(connectionSocket.getOutputStream());
// Change keep alive connection header to close, add connection header if it doesn't exist
while ((input = in.readLine()) != null) {
if (foundConnectionHeader) {
requestHeaders.add(input);
} else {
if (input.contains("Proxy-Connection: keep-alive")) {
requestHeaders.add("Proxy-Connection: close");
foundConnectionHeader = true;
} else {
requestHeaders.add(input);
}
}
// System.out.println(input);
}
if (!foundConnectionHeader) {
requestHeaders.add("Proxy-Connection: close");
}
System.out.println("DONE");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
It will return null when the peer disconnects.
If you're going to implement HTTP you need a good knowledge of RFC 2616, especially the parts about content length and connection lifetime. Your present code doesn't begin to be adequate.
I am attempting a client/server type chat box (using GUI's). I won't get into details of the multi-threading I used in the program since I believe it is not part of the problem (I hope not) and it will be good amount of code to post. Anyways, for both my client and my server I create a socket, and some other stream classes within a try block, and some reason the sockets close after the catch blocks. PS I do NOT call socket.close() method anywhere that could end if early
Server, this is ran into a constructor of one of my class. It breaks down into, my main has the actually server stuff on a different thread, (like my previous post) it is a fix so that the gui can load and run the server stuff without one waiting on the other. Anyways, without all that detail, here is my code
public ChatAppProtocol(Socket sock)
{
super("ChatAppServer");
// this also has a clas var of Socket
this.sock = sock;
try (
PrintWriter output = new PrintWriter(this.sock.getOutputStream(), true);
BufferedReader input = new BufferedReader(new InputStreamReader(this.sock.getInputStream())) ;
)
{
// first stream of a string is the username loging in from client
String name = input.readLine();
// this returns false, so its not closed
System.out.println("closed?: " + this.sock.isClosed());
}
catch (IOException e)
{
e.printStackTrace();
}
// PROBLEM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// closed after the catch blocks before methods even ends
// p.s. i also plan on using the socket in another method but can't since it closes
System.out.println("closed?: " +this.sock.isClosed());
}
now my client
#FXML
private void login()
{
this.name = this.username.getText().trim();
this.portnum = Integer.parseInt(this.port.getText());
this.name = this.username.getText().trim();
this.ipaddr = this.ip.getText().trim();
try (t
Socket socket = new Socket(this.ipaddr, this.portnum);
PrintWriter output = new PrintWriter(socket.getOutputStream(), true);
)
{
this.sock = socket;
output.println(this.name);
// this returns false, not closed
System.out.println("closed?: " +this.sock.isClosed());
}
catch (UnknownHostException e)
{
System.err.println("Problem at ip: " + this.ipaddr);
System.exit(1);
}
// PROBLEM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// returns true here, closes before methods end and i cant reuse it
System.out.println("IS IT CLOSED!!!!!! " + this.sock.isClosed());
}
}
so, any reason why both this different class, different files, different project sockets close after try-catch blocks? Can't find answer online, and been on it for a while and I am stuck. I found out about this problem after seeing this on the server side console
java.net.SocketException: Socket is closed
at java.net.Socket.getOutputStream(Socket.java:943)
at chatappserver.ChatAppProtocol.run(ChatAppProtocol.java:62)
Because you're creating socket with the brackets of the try block, it is automatically closed upon exiting the block. Instead, try creating it inside the block itself and it shouldn't be closed:
try {
this.sock = new Socket(this.ipaddr, this.portnum);
PrintWriter output = new PrintWriter(socket.getOutputStream(), true);
output.println(this.name);
} catch (UnknownHostException e) {
System.err.println("Problem at ip: " + this.ipaddr);
System.exit(1);
}
// this.sock should still be open at this point.
Have a read of the Java tutorial on try-with-resources for more information on why you're getting your current behaviour.
You are using try-with-resources, which is roughly an equivalent of:
try
{
this.sock = new Socket(this.ipaddr, this.portnum));
output.println(this.name);
// this returns false, not closed
System.out.println("closed?: " +this.sock.isClosed());
}
catch (UnknownHostException e)
{
System.err.println("Problem at ip: " + this.ipaddr);
System.exit(1);
} finally {
if (this.sock != null)
this.sock.close();
}
Just initialize the socket outside the resources clause of try (...) and it won't get closed
I've seen many different examples of using HttpURLConnection + InputStream, and closing them (or not closing them) after use. This is what I came up with to make sure everything is closed after finished, whether there's an error or not. Is this valid?:
HttpURLConnection conn = null;
InputStream is = null;
try {
URL url = new URL("http://example.com");
// (set connection and read timeouts on the connection)
conn = (HttpURLConnection)url.openConnection();
is = new BufferedInputStream(conn.getInputStream());
doSomethingWithInputStream(is);
} catch (Exception ex) {
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
if (conn != null) {
conn.disconnect();
}
}
Thanks
Yep.. Doing the end part in finally would be best idea because if code fails somewhere, program won't reach till .close(), .disconnect() statements that we keep before catch statements...
If the code fails somewhere and exception is thrown in between of the program, still finally get executed regardless of exception thrown...
There is also the new (with Java 7) 'try()' technique
try (OutputStream os = http.getOutputStream()) {
os.write(out);
}
Basically, it will auto-close anything in the try() statement, regardless of whether it is successful or not.