Reputation: 2780
Currently at my company we received Sonarqube reviews and in one of them, there's this warning about not using try-with-resources
statement (see below):
public static void main(String[] args) throws Exception {
Socket s1 = null;
Socket s2 = null;
try {
String host = InetAddress.getByName("myLocalHost").getHostAddress();
int port = Integer.parseInt(System.getenv("Port");
s1 = new Socket(host, port);
s2 = new Socket(host2, port2);
... }
...}
The solution to this problem might look straightforward, that is, I can wrap the Socket variables inside the try () resources
, but in order for doing this I need to declare the host and port variables outside of the try
statement. My concern about this solution is that the variables that are outside of this try
statement are now unprotected in case no host or port number is given.
public static void main(String[] args) throws Exception {
String host = InetAddress.getByName("myLocalHost").getHostAddress();
int port = Integer.parseInt(System.getenv("Port");
try (
Socket s1 = new Socket(host, port);
Socket s2 = new Socket(host2, port2);
) {
....
}
}
My question is if there's a better way to protect these variables that were left outside of the try
statement or if the approach that I am following can be enough.
Upvotes: 0
Views: 87
Reputation: 298233
You don’t need to connect immediately within the Socket
’s constructor; you can create the instances first and connect later:
try(Socket s1 = new Socket(); Socket s2 = new Socket()) {
InetAddress host = InetAddress.getByName("myLocalHost");
int port = Integer.parseInt(System.getenv("Port"));
s1.connect(new InetSocketAddress(host, port));
InetAddress host2 = InetAddress.getByName("secondHost");
int port2 = Integer.parseInt(System.getenv("Port2"));
s2.connect(new InetSocketAddress(host2, port2));
// use the Socket
}
There’s no problem in closing a Socket
that never got connected, i.e. when an exception occurred after its creation but before the connect
call.
Note that the code above uses the resolved InetAddress
, instead of calling getHostAddress()
to get a string that will be resolved again during the connect operation.
By removing this redundant operation, you could also write
try(Socket s1 = new Socket("myLocalHost",Integer.parseInt(System.getenv("Port")));
Socket s2 = new Socket("secondHost", Integer.parseInt(System.getenv("Port2")))) {
// use the Socket
}
This will resolve the name in the socket’s constructor in the first place. If an exception occurs, all resources that have been allocated so far, will be released.
Upvotes: 1