0
I’m working with a thread that keeps running Broadcasts to map network devices, but when I modify my code and Spring performs Hot Swap, I get Exception "Bindexception: Address already in use: Cannot bind".
Applying:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class BroadcastListeningThread {
public static void startThreadToListenToBroadcasts() {
new Thread() {
@Override
public void run() {
try (DatagramSocket socket = new DatagramSocket(30333, InetAddress.getByName("0.0.0.0"))) {
socket.setBroadcast(true);
var responseBuffer = new byte[1024];
var responsePacket = new DatagramPacket(responseBuffer, responseBuffer.length);
String receivedResponse;
while (true) {
socket.receive(responsePacket);
receivedResponse = new String(responsePacket.getData(), 0, responsePacket.getLength());
System.out.println(receivedResponse);
DiscoveredWEXEquipments.addEquipment(receivedResponse);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
}
Error:
java.net.BindException: Address already in use: Cannot bind
at java.base/java.net.DualStackPlainDatagramSocketImpl.socketBind(Native Method)
at java.base/java.net.DualStackPlainDatagramSocketImpl.bind0(DualStackPlainDatagramSocketImpl.java:84)
at java.base/java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:131)
at java.base/java.net.DatagramSocket.bind(DatagramSocket.java:394)
at java.base/java.net.DatagramSocket.<init>(DatagramSocket.java:244)
at java.base/java.net.DatagramSocket.<init>(DatagramSocket.java:301)
at br.com.manager.utils.CommunicationHelper.udpMessage(CommunicationHelper.java:16)
at br.com.manager.equipmentdiscovery.DiscoverUsingBroadcastStrategy.lambda$0(DiscoverUsingBroadcastStrategy.java:18)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at br.com.manager.equipmentdiscovery.DiscoverUsingBroadcastStrategy.findAll(DiscoverUsingBroadcastStrategy.java:16)
at br.com.manager.equipmentdiscovery.DiscoverNetworkEquipmentsInNetwork.run(DiscoverAllNetworkEquipmentsInNetwork.java:11)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:770)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1213)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1202)
at br.com.manager.ManagerApplication.main(ManagerApplication.java:11)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
I solved the problem by creating a variable to use in while:
public static boolean exit = false;
and set to true before starting threads:BroadcastListeningThread.exit = true;
– Luis Felipe Machado
Great, I was trying something along the lines of doing "stop" on Thread or not recreating it if it already existed. https://docs.oracle.com/javase/8/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
– Renan.Silvano
My supervisor suggested creating a method within the class
startThreadToListenToWex350Broadcasts()
and use the Annotation @Predestroy, instead of setting the value ofexit
at the beginning of the application. The purpose of this method should be to release Resources or perform any other Cleanup tasks before the bean gets destroyed, for example closing a database Connection.– Luis Felipe Machado