I am using Asterisk with asterisk-java library to detect events. The follwoing code excerpt shows my usage. The connection should stay open, but it just closes after initializing when i am not using a endless loop. How can i keep the connection till the application closes?
[...]
public AsteriskManager(AsteriskAccountData asteriskAccountData)
throws ManagerCommunicationException {
this.asteriskAccountData = asteriskAccountData;
this.asteriskStateModel = new AsteriskStateModel();
new Thread(() -> {
asteriskServer = new DefaultAsteriskServer(
asteriskAccountData.getHost(),
asteriskAccountData.getUser(),
asteriskAccountData.getPassword()
);
ManagerConnectionFactory factory = new ManagerConnectionFactory(
asteriskAccountData.getHost(),
asteriskAccountData.getUser(),
asteriskAccountData.getPassword()
);
this.managerConnection = factory.createManagerConnection();
try {
asteriskServer.addAsteriskServerListener(this);
managerConnection.addEventListener(this);
registerListener();
//FIXME endless thread
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} catch (ManagerCommunicationException ex) {
//FIXME error handling
}
}, "AsteriskManagerThread").start();
}
[...]
Related
I have the following mutlithreaded code. I want the LatchCode.doStuff() to wait until UncaughtExceptionHandler handler completes it work, but it wasn't. How could I make the main thread to wait for it. I need to propagate the exception to parent for some project requirement to log the error into DB (should happen at the end of processing). Following is the piece of code.
public class LatchExceptionTest {
public static void main(String[] args) {
LatchCode l = new LatchCode();
Cont c = new Cont();
try {
l.doStuff(c);
System.out.println("Main Thread - work completed");
if(!c.err.isEmpty())
throw new Exception(c.err.toString());
} catch (Exception e) {
System.out.println("trace printing start");
System.out.println(c.err.toString()); // log errors to DB
System.out.println("trace printing edn");
}
}
}
class LatchCode {
public void doStuff(final Cont cont) throws RuntimeException, InterruptedException {
System.out.println("Intermediate class start");
try {
Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread th, Throwable ex) {
cont.err.add(ex.getMessage());
}
};
Thread aggregatorThread = new Thread(() -> {
try {
if(cont.err.size() > 0)
return;
System.out.println("AGGREGATOR thread START");
Thread.sleep(3000);
System.out.println("AGGREGATOR thread END");
} catch (Exception e) {
throw new RuntimeException(e);
}
});
CyclicBarrier barrier = new CyclicBarrier(2, aggregatorThread);
AA a = new AA();
BB b = new BB();
CountDownLatch latch = new CountDownLatch(2);
Thread one = new Thread(() -> {
try {
a.doSomething();
} catch (Exception e) {
System.out.println("Exception in 1");
//Thread.currentThread().interrupt();
throw new RuntimeException(e.toString());
} finally {
try {
barrier.await();
} catch (Exception e) {
System.out.println("Exception in 1 finallt");
throw new RuntimeException(e.toString());
} finally {
latch.countDown();
}
}
});
Thread two = new Thread(() -> {
try {
b.doSomething();
} catch (Exception e) {
System.out.println("Exception in 2");
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} finally {
try {
barrier.await();
} catch (Exception e) {
System.out.println("Exception in 2 finallt");
throw new RuntimeException(e);
} finally {
latch.countDown();
}
}
});
one.start();
two.start();
one.setUncaughtExceptionHandler(h);
two.setUncaughtExceptionHandler(h);
latch.await();
} catch (Exception e) {
System.out.println("Exception in caller");
throw new RuntimeException(e);
} finally {
System.out.println("Intermediate class end");
}
}
}
class AA {
public void doSomething() throws Exception {
try {
System.out.println("1 start");
Thread.sleep(1);
throw new Exception("In AA");
} catch (Exception e) {
System.out.println("Exception in AA");
throw new Exception(e.toString());
}
}
}
class BB {
public void doSomething() throws Exception {
try {
System.out.println("2 start");
Thread.sleep(1);
} catch (Exception e) {
System.out.println("Exception in BB");
}
System.out.println("2 end");
}
}
class Cont {
ConcurrentLinkedQueue<String> err = new ConcurrentLinkedQueue<String>();
}
If AA.doStuff() and BB.doStuff() has loger sleeps, then I could Cont.err is not empty and getting into catch block. But whne sleep time is negligible like 1 ms, then if block in main() failed and program is executing as if there is no exception.
So I need calling thread to wait for UncaughtExceptionHandler completion. Could some one help on this.
Thanks in advance
After making exhaustive search, found the following page. Go through the details on how things work in UEH.
https://bugs.openjdk.java.net/browse/JDK-8153487
Excerpt from the above thread for short answer:
There is no guarantee that UncaughtExceptionHandlers have run before awaitTermination returns.
It is a pool thread that sets the state to TERMINATED, so it cannot wait for all pool threads to terminate!
It seems unlikely we can make this better. It seems that relying on the UEH in this way is a poor design
I am trying to check if internet is on or not constantly every 5 seconds, I wrote below code but some how it always go inside wait() and waiting infinite.
Code I wrote :
Socket socket = null;
public void checkInternetConnectivity() throws InterruptedException {
boolean reachable = false;
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
try {
socket = new Socket("xxx.xxx.xxx.x", xx);
} catch (UnknownHostException e) {
stopApp();
} catch (IOException e) {
stopApp();
}
}
}, 0, 5, TimeUnit.SECONDS);
synchronized (this) {
wait();
}
}
private void stopApp() {
System.out.println("Internet Not Available stopping app");
System.exit(0);
}
It always stuck inside below :
synchronized (this) {
wait();
}
You could do:
InetAddress.isReachable
Depending on what your needs are you should consider trying reach a specific host by
private static boolean googleIsAvailable() {
try {
final URL url = new URL("http://www.google.com");
final URLConnection connection = url.openConnection();
connection.connect();
connection.getInputStream().close();
return true;
} catch (MalformedURLException e) {
throw new RuntimeException(e);
} catch (IOException e) {
return false;
}
}
If your are communicating with a webservice the webservice should provide a GET method to check if it is available.
If you need to check constantly try somthing like
Socket s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT);
while(s.isConnected()){
//do your stuff
}
You should also check out the keepAlive Option.
But the more important question is what happen in your application if internet connection is not available anymore?
Most methods throw Exceptions if a Server is not available anymore.
You could just catch them and react on it.
I'm currently writing a client-server application where data should be transferred to the server to process the data. For building the connection I use ServerSocket and Socket and for sending the data I use OutputStream + ObjectOutputStream on the client-side and InputStream + ObjectInputStream on the server-side. The connection is currently running on localhost.
The object I try to transfer is a serializable class that only contains String parameters.
The problem I'm facing now is that readObject() immediately throws an EOFException as soon as the OutputStreams of the client are initialized (which leads to an initialization of the InputStreams of the server at the same time) instead of waiting for input from the client.
I send the data from the client using this code:
public void send(DataSet dataSet) {
if (!clientStreamsEstablished) {
initiateClientStreams();
}
try {
out.writeObject(dataSet);
} catch (IOException e) {
e.printStackTrace();
}
}
This method is only called when I hit the "submit"-button in the UI so it will not be executed on start of the application.
The data is currently (already tried a ton of other approaches with and without while() loop etc., etc.) read on the server using this method:
private void waitForInput(ObjectInputStream in, InputStream listeningPort) {
boolean dataReceived = false;
DataSet dataSet = null;
System.out.println("waiting ...");
while (!dataReceived) {
try {
Object temp = in.readObject(); // <-- EOFException is thrown here
boolean test = false;
if (temp instanceof DataSet) {
dataSet = (DataSet) temp;
}
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
break;
}
}
System.out.println("Test 2: " + dataSet.toString());
if (dataReceived) {
waitForInput(in, listeningPort);
}
}
As soon as the client thread on the server reaches this line (see code-comment above) I get this stacktrace:
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2626)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1321)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
at com.labdashboardserver.ClientThread.waitForInput(ClientThread.java:53)
at com.labdashboardserver.ClientThread.run(ClientThread.java:43)
Exception in thread "Thread-2" java.lang.NullPointerException
at com.labdashboardserver.ClientThread.waitForInput(ClientThread.java:65)
at com.labdashboardserver.ClientThread.run(ClientThread.java:43)
The reason for the second part of the stacktrace containing the NullPointerException is apparent as due to the EOFExcpetion the dataSet never is initialized.
However from my point of view readObject() should block and wait for the client to send ANY data before starting to read it and throw an EOF. I feel like I read through half of Stack Overflow and other forums searching for an answer but the articles I found only discuss reading files or only immediate temporary streams which are closed afterwards.
Edit
I initialize the connection before calling the UI in my main method:
public static void main(String[] args) {
connector = new LabConnector();
connector.run();
if (connector.getConnectionEstablished()) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame = new LabUI();
frame.setVisible(true);
} catch (Exception e) {
JOptionPane.showMessageDialog(null,
"Error Message:\n" + e.getMessage() + "\nProgram shutting down!", "Critical Error", 0);
}
}
});
}
While in the LabConnector class I initialize the streams and connection like this:
public void run() {
try {
establishConnection();
} catch (UnknownHostException e) {
retryConnection(e);
} catch (IOException e) {
retryConnection(e);
}
if (connectionEstablished) {
initiateClientStreams();
}
}
private void establishConnection() throws UnknownHostException, IOException {
client = new Socket(HOST_IP_ADRESS, HOST_PORT);
JOptionPane.showMessageDialog(null, "Connected to Server!");
connectionEstablished = true;
}
private void initiateClientStreams() {
try {
sendingPort = client.getOutputStream();
out = new ObjectOutputStream(sendingPort);
clientStreamsEstablished = true;
} catch (IOException e) {
e.printStackTrace();
}
}
I have a classic server-multi-clients program. Tthe server listens to ServerSocket and for each incoming socket it builds a new Runnable class and executes it in ExecuteService.
In the run method of the Runnable class, I open try-with-resources block and in the try I have a while loop that reads from inputstream and writes to outputstream until it receives FIN command from the clients. Everything works fine and the clients disconnect successfully. The run reaches the finally block and prints some stuff for testing, but it doesn't exit the try block so it does not exit the run method and I am stuck in the run somewhere, maybe the read method of the inputstream.
I can post the code if anyone interested.
How can I force close everything in the finally and exit the run method?
The code:
Server.java:
public static void main(String[] args) {
playersReady = new ArrayList<Integer>();
ServerSocket server = null;
try {
server = new ServerSocket(Consts.PORT);
ExecutorService service = Executors.newFixedThreadPool(characters.size());
while(playersReady.size()<characters.size()){
RequestHandler handler = new RequestHandler(server.accept());
service.execute(handler);
}
service.shutdownNow();
service.shutdown();
while(!service.isTerminated()){}
System.out.println("finished");
RequestHandler.java
public final class RequestHandler implements Runnable {
.....
public void run() {
//DataOutputStream output = null;
//DataInputStream input = null;
try (DataOutputStream output = new DataOutputStream(socket.getOutputStream());
DataInputStream input = new DataInputStream(socket.getInputStream())){
// socket.setSoTimeout(500);
handleReady(input.readUTF().split(" "), output);
while (/*!shutdown && !socket.isClosed() && */socket.isConnected()) {
System.out.println("check before read " + character.getId());
String request = input.readUTF();
System.out.println("check after read " + character.getId());
System.out.println("-----------------------------------" + request);
if (shutdown) {
socket.shutdownInput();
socket.getOutputStream().flush();
socket.shutdownOutput();
break;
}
String[] requestParser = request.split(" ");
if (requestParser[1].equals("DMG")) {
// handle damage request
handleDamage(requestParser, output);
} else if (requestParser[1].equals("BND")) {
// handle bandage request
handleBandage(requestParser, output);
} else if (requestParser[1].equals("FIN")) {
// handle finish request
handleFin();
if (!socket.isClosed())
socket.shutdownInput();
if (!socket.isClosed()) {
socket.getOutputStream().flush();
socket.shutdownOutput();
}
shutdown = true;
break;
} else {
break;
}
}
} catch (SocketTimeoutException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
e.printStackTrace();
shutdown = true;
break;
} catch (Throwable e) {
e.printStackTrace();
} finally {
try {
System.out.println("finished");
if (!socket.isClosed())
socket.shutdownInput();
if (!socket.isClosed()) {
socket.getOutputStream().flush();
socket.shutdownOutput();
socket.close();
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("Done run");
}
....
The System.out.println("finished") in the finally is printed,
but the System.out.println("Done run") in the end of the run method does not!!
Why?
It stuck in the run method, I think in the readUTF call, but I closed all the resources!
You return before that line, that's why it is not run. The finally block is run anyway, because it is a finally block. Finally blocks are always run, there is only one exception from this rule: System.exit(), but this is not the case.
I am trying to create a UDP listener that will listen on a separate thread. It works fine the first time but when I stop the connection and then start it again it gives me errors.
listenerRunnable = new Runnable() {
public void run() {
//This thread will listen keep listening to the UDP traffic and put it to the log source string
try {
sock = new DatagramSocket(portNumber);
} catch (SocketException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(keepListening) {
try {
pack = new DatagramPacket(recievedData, BUFFERSIZE);
sock.receive(pack);
String data = new String(pack.getData(), 0, pack.getLength());
addToLog(data);
System.out.println(data);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sock.close();
}
}
};
/**
* Function to start the listening thread.
*/
public void startListening(int portNum) {
keepListening = true;
portNumber = portNum;
listenerThread = new Thread(listenerRunnable);
logSource_buffer = "";
logSourcehtml_buffer = "";
logSourcehtml_temp = "";
ipListIndex_beg = 0;
ipListIndex_end = -1;
if(!listenerThread.isAlive()) {
listenerThread.start();
}
}
/**
* stops the listening thead. When the listening thread sees that keepListening is set to false
* it will reach the end of its loop, close the socket, and the thread will die.
*/
public void stopListening() {
keepListening = false;
}
It gives me the following error:
logUpdatingThread has entered synchronized block!!!
java.net.SocketException: Unrecognized Windows Sockets error: 0: Cannot bind
at java.net.PlainDatagramSocketImpl.bind0(Native Method)
at java.net.PlainDatagramSocketImpl.bind(Unknown Source)
which points to the line with sock.recieve(pack);
It seems like for some reason the socket isn't closing because, I think, its waiting at sock.recieve(pack) and never gets out of the while loop to close the socket. How would I get around this though?
Thanks
As Peter Tillemans said, you should set a receive timeout so that you're not sitting there trying to receive() for ever.
Also, keep hold of the Thread object returned by new Thread(listenerRunnable) so that your stopListening() method can wait for the thread to die:
public void stopListening() {
keepListening = false;
listenerThread.join();
}
You'll have to add a setSoTimeout(timeout) before calling receive. This will regularly throw SocketTimeoutExceptions, but keeping the Datagram socket open. This will allow you to regularly check the loop variable.
Additionally you should move the loop inside the first try-catch block and add a finally block to close the socket.
like :
try {
sock = new DatagramSocket(portNumber);
sock.setSoTimeout(250);
while(keepListening) {
try {
pack = new DatagramPacket(recievedData, BUFFERSIZE);
sock.receive(pack);
String data = new String(pack.getData(), 0, pack.getLength());
addToLog(data);
System.out.println(data);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (SocketException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} finally {
sock.close();
}