call finally before system exit - java

Can anyone tell me how to execute finally still if an exception raised and the catch is calling System.exit
try {
} catch (Exception e) {
System.exit(0);
} finally {
System.out.println("closing the conn");
}

System.exit() normally never returns so you will not execute the code in the finally block as you have it written.
One way you can do it is to note the fact that you had an error in the catch block then do the exit in the finally block.
boolean error = false;
try {
// bla bla blaa
} catch (Exception e) {
error = true;
}
finally {
if (error) {
System.exit(0);
}
}
Another way to do it is to add a shutdown hook that will get called as the JVM is exiting.
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Do your shutdown stuff here");
}
}));
try {
// bla bla blah
} catch (Exception e) {
System.exit(0);
} finally {
}

Related

JavaFX how to change scene within a runnable

I'm having an app which enables a customer to place an order for a ride (as in Uber), initially considered in a "WAITING" phase. When a driver accepts the order, it is automatically set in an "ACCEPTED" phase.
When ACCEPTED, the user is going to be redirected to another scene, telling him that he needs to wait for his rider to pick him up.
I decided to create a thread that checks every 250ms if the status of his order was set to ACCEPTED, like that:
public class AcceptanceRunnable implements Runnable {
private boolean running;
public AcceptanceRunnable() {
running = true;
}
public void run() {
do {
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (OrderService.checkIfAccepted(OrderSession.getOrder())) {
// move to other scene
break;
}
} while(running);
}
public void setRunning(boolean running) {
this.running = running;
}
}
This AcceptanceRunnable class gets instantiated within the controller in the initialize() method:
#FXML
public void initialize() throws InterruptedException, IOException {
sourceAddress.setText("From: " + OrderSession.getOrder().getSourceAddress());
destinationAddress.setText("To: " + OrderSession.getOrder().getDestinationAddress());
price.setText("You'll need to pay RON " +
UserService.calculatePrice(UserSession.getUser()) + " for this ride.");
acceptanceRunnable = new AcceptanceRunnable();
Thread t = new Thread(acceptanceRunnable);
t.start();
}
Everything works fine. If I just print out some lines while waiting for the order's status to get changed, it seems to be okay. The problem is, I want my user to be redirected to another scene, if his order gets accepted.
This means, I need to insert something in place of the comment made in my AcceptanceRunnable.run() method.
I also tried changing the scene by having a method called ifAccepted() inside my controller, which actually triggers the method that changes the scene:
if (OrderService.checkIfAccepted(OrderSession.getOrder())) {
try {
Class<?> controller = Class.forName("com.example.yuber.controllers.CustomerWaitController");
Method ifAccepted = controller.getMethod("ifAccepted");
ifAccepted.invoke(controller.newInstance());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
break;
}
But I only get some NullPointerException and I'm pretty sure that what I do here isn't really correct.
Any opinions?
As Slaw suggested, using Platform#runLater(Runnable) fixed my problem.
What I actually did was add my run() method from the Runnable inside my controller, renaming it to handleTread():
public void handleThread() {
do {
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (OrderService.checkIfAccepted(OrderSession.getOrder())) {
Platform.runLater(() -> {
try {
SceneService.NewScene("/com/example/yuber/accepted-view.fxml", (Stage) rootPane.getScene().getWindow(), rootPane.getScene());
} catch (IOException e) {
e.printStackTrace();
}
});
break;
}
} while(running);
}
Not using Platform.runLater(...) would result in receiving a Not on FX Application Thread error.
Everything seems to be fine now.

Android Studio Thread not waiting for response from distributed network (iota tangle)

I'm using the ReadData class from https://github.com/iota-community/java-iota-workshop/blob/master/src/main/java/com/iota/ReadData.java to retrieve a message from the Iota Tangle (essentially a distributed Network) via a hash value (the bundlehash).
That's my method:
private String readMessageFromHash(String BundleHash) {
final String[] s = new String[]{""};
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
s[0] = ReadData.getTMessage(BundleHash);
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return s[0];
}
I need the return value in my next line of code but without multithreading my program crashes.
With mutlithreading it sometimes works, but most of time it doesn't work (returns an empty String).
I tried using:
thread.start();
try {
while(s[0].length < 1){}
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return s[0];
but it just loops infinitely.
I think the issue is my program not waiting long enough for a response from the network.

Java thread exit without warning

my java thread exit with any warning. I have no idea why the thread exit. I can't find it in jstack. And it seems the log code hadn't run. My code below:
private class WorkThread extends Thread {
public WorkThread() {
super("work-thread");
setDaemon(false);
}
#Override
public void run() {
logger.info("start running thread work-tracker");
try {
while (!interrupted()) {
try {
// do something
} catch (Throwable e) {
logger.error("ignore all exception", e);
}
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
} finally {
logger.error("work thread exit interrupted status: {}", interrupted());
}
}
}
I cannot find the log "work thread exit interrupted status" and anything about "work-thread" in the jstack log. any suggestion?
private class WorkThread extends Thread {
public WorkThread() {
super("work-thread");
setDaemon(false);
}
#Override
public void run() {
logger.error("start running thread work-tracker");
try {
while (!interrupted()) {
try {
// do something
} catch (Throwable e) {
logger.error("ignore all exception");
}
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
}
Thread.currentThread().interrupt();
}
} finally {
logger.error("work thread exit interrupted status: {}" +interrupted());
}
}
}

How to keep a thread alive forever until JVM is killed?

I have a thread which i wanted to run always until the JVM is stopped. What is the best way to do that ?
public void run() {
String event = sc.nextLine();
try {
queue.put(event); // thread will block here
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Just adding an infinite loop should do the trick
public void run() {
while(true){
String event = sc.nextLine();
try {
queue.put(event); // thread will block here
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
while (true) { runBody(); }
Add exception handling if necessary.

Apache Commons Net FTPClient abort file store

I'm developing an applet to allow FTP upload from a webapp...
The send operation is working fine, but I'd like to able to cancel a file storing in progress.
I'm not very fluent with threads. My first attempt was to call ftp.abort() in the cancel thread, but the abort method was only called when the storeFile method finished, like if the send thread was locking the ftp object.
So I changed the code to interrupt the send thread and check it in the copy stream listener. The file storing stops as expected, but ftp.abort() call hangs the application, it never complete.
Any ideas?
Thanks,
Philip
Send operation:
botaoEnviar.setEnabled(false);
botaoCancelar.setEnabled(true);
textField.requestFocus();
threadEnvio = new Thread(new Runnable()
{
#Override
public void run()
{
FileInputStream fis = null;
try
{
if(arquivoSelecionado == null)
{
throw new IllegalArgumentException("Arquivo deve ser informado");
}
try
{
ftp = new FTPClient();
ftp.connect("192.168.1.243");
}
catch(Exception e)
{
throw new FtpConnectionException("Não foi possível conectar no servidor FTP", e);
}
if(!ftp.login("c001", "0AJF2J36"))
{
throw new IllegalArgumentException("Não foi possível autenticar no servidor FTP");
}
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ftp.setCopyStreamListener(new CopyStreamAdapter()
{
#Override
public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize)
{
if(threadEnvio.isInterrupted())
{
try
{
ftp.abort();
}
catch(IOException ex)
{
handleException(ex);
}
}
else
{
int percent = (int) (totalBytesTransferred * 100 / arquivoSelecionado.length());
progressBar.setValue(percent);
}
}
});
fis = new FileInputStream(arquivoSelecionado);
if(ftp.storeFile(arquivoSelecionado.getName(), fis))
{
JOptionPane.showMessageDialog(null, "Arquivo enviado com suceso");
}
else
{
JOptionPane.showMessageDialog(null, "Não foi possível enviar o arquivo", "Erro", JOptionPane.ERROR_MESSAGE);
}
ftp.logout();
}
catch(Exception e)
{
handleException(e);
}
finally
{
if(fis != null)
{
try
{
fis.close();
}
catch(IOException ex)
{
handleException(ex);
}
}
if(ftp != null)
{
try
{
ftp.disconnect();
}
catch(IOException ex)
{
handleException(ex);
}
}
progressBar.setValue(0);
botaoEnviar.setEnabled(true);
botaoCancelar.setEnabled(false);
}
}
});
threadEnvio.start();
Cancel operation:
botaoCancelar.setEnabled(false);
new Thread(new Runnable()
{
#Override
public void run()
{
try
{
threadEnvio.interrupt();
}
catch(Exception ex)
{
handleException(ex);
}
finally
{
botaoCancelar.setEnabled(true);
}
}
}).start();
interrupting a thread like this is not correct, it causes your thread to wait for some seconds at exactly which line that compiler is reading in your thread
the only way that you can abort your ftp upload is to make the thread sleep for some time
then abort your upload and wait for the thread to complete itself
see this :
try {
try {
Thread.currentThread();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
mFTP.abort();
} catch (IOException e) {
e.printStackTrace();
}
} catch (NetworkOnMainThreadException e) {
e.printStackTrace();
}

Categories